{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Initialize Folders"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "from __future__ import print_function\n",
    "from imutils import paths\n",
    "import os\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib\n",
    "import numpy as np\n",
    "import keras\n",
    "\n",
    "from keras.preprocessing import image as image_utils\n",
    "from keras.preprocessing.image import load_img\n",
    "from keras.preprocessing.image import img_to_array\n",
    "from keras.preprocessing.image import array_to_img\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "from keras.models import *\n",
    "from keras.layers import *\n",
    "from keras.optimizers import *\n",
    "from keras.callbacks import ModelCheckpoint, LearningRateScheduler, TensorBoard\n",
    "from keras import backend as keras\n",
    "#from keras.layers.advanced_activations import LeakyReLU, PReLU\n",
    "\n",
    "\n",
    "#import skimage.io as io\n",
    "#import skimage.transform as trans\n",
    "\n",
    "#K.set_image_data_format(\"channels_last\")\n",
    "\n",
    "%matplotlib inline\n",
    "%load_ext autoreload\n",
    "%autoreload 2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "root_dir = './data'\n",
    "training_data_dir = os.path.join(root_dir, 'train/images')\n",
    "training_data_mask_dir = os.path.join(root_dir, 'train/masks')\n",
    "\n",
    "val_data_dir = os.path.join(root_dir, 'val/images')\n",
    "val_data_pred_dir = os.path.join(root_dir, 'val/predict')\n",
    "val_data_mask_dir = os.path.join(root_dir, 'val/masks')\n",
    "\n",
    "test_data_dir = os.path.join(root_dir, 'test/images')\n",
    "test_data_pred_dir = os.path.join(root_dir, 'test/predict')\n",
    "test_data_mask_dir = os.path.join(root_dir, 'test/masks')\n",
    "\n",
    "img_rows = 256\n",
    "img_cols = 256"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Define Loss function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Define loss function\n",
    "def jaccard_coef(y_true, y_pred):\n",
    "    smooth = 1.\n",
    "    y_true_f = K.flatten(y_true)\n",
    "    y_pred_f = K.flatten(y_pred)\n",
    "    intersection = K.sum(y_true_f * y_pred_f)\n",
    "    return  (intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) - intersection + smooth)\n",
    "\n",
    "def jaccard_coef_loss(y_true, y_pred):\n",
    "    smooth = 1.\n",
    "    y_true_f = K.flatten(y_true)\n",
    "    y_pred_f = K.flatten(y_pred)\n",
    "    intersection = K.sum(y_true_f * y_pred_f)\n",
    "    j = -(intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) - intersection + smooth)\n",
    "    if (j > 0.65):\n",
    "        j = j - 1\n",
    "    return j"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def normalizeData_rgb(img,mask):\n",
    "    for i in range(3):\n",
    "        mean = np.mean(img[:,:,i])  # mean for data centering\n",
    "        std = np.std(img[:,:,i])  # std for data normalization\n",
    "        img[:,:,i] -= mean\n",
    "        img[:,:,i] /= std\n",
    "    mask = mask /255\n",
    "    mask[mask > 0.5] = 1\n",
    "    mask[mask <= 0.5] = 0\n",
    "    return (img,mask)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def normalizeData(img,mask):\n",
    "    mean = np.mean(img)  # mean for data centering\n",
    "    std = np.std(img)  # std for data normalization\n",
    "    img -= mean\n",
    "    img /= std\n",
    "    mask = mask /255\n",
    "    mask[mask > 0.5] = 1\n",
    "    mask[mask <= 0.5] = 0\n",
    "    return (img,mask)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def trainGenerator(batch_size,train_path,image_folder,mask_folder,aug_dict,image_color_mode = \"rgb\",\n",
    "                    mask_color_mode = \"grayscale\",image_save_prefix  = \"image\",mask_save_prefix  = \"mask\",\n",
    "                    flag_multi_class = False,num_class = 2,save_to_dir = None,target_size = (256,256),seed = 1):\n",
    "    '''\n",
    "    can generate image and mask at the same time\n",
    "    use the same seed for image_datagen and mask_datagen to ensure the transformation for image and mask is the same\n",
    "    if you want to visualize the results of generator, set save_to_dir = \"your path\"\n",
    "    '''\n",
    "    image_datagen = ImageDataGenerator(**aug_dict)\n",
    "    mask_datagen = ImageDataGenerator(**aug_dict)\n",
    "    image_generator = image_datagen.flow_from_directory(\n",
    "        train_path,\n",
    "        classes = [image_folder],\n",
    "        class_mode = None,\n",
    "        color_mode = image_color_mode,\n",
    "        target_size = target_size,\n",
    "        batch_size = batch_size,\n",
    "        save_to_dir = save_to_dir,\n",
    "        save_prefix  = image_save_prefix,\n",
    "        seed = seed)\n",
    "    mask_generator = mask_datagen.flow_from_directory(\n",
    "        train_path,\n",
    "        classes = [mask_folder],\n",
    "        class_mode = None,\n",
    "        color_mode = mask_color_mode,\n",
    "        target_size = target_size,\n",
    "        batch_size = batch_size,\n",
    "        save_to_dir = save_to_dir,\n",
    "        save_prefix  = mask_save_prefix,\n",
    "        seed = seed)\n",
    "    train_generator = zip(image_generator, mask_generator)\n",
    "    for (img,mask) in train_generator:\n",
    "        img,mask = normalizeData_rgb(img,mask)\n",
    "        yield (img,mask)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def validationGenerator(batch_size,train_path,image_folder,mask_folder,aug_dict,image_color_mode = \"rgb\",\n",
    "                    mask_color_mode = \"grayscale\",image_save_prefix  = \"image\",mask_save_prefix  = \"mask\",\n",
    "                    flag_multi_class = False,num_class = 2,save_to_dir = None,target_size = (256,256),seed = 1):\n",
    "    '''\n",
    "    can generate image and mask at the same time\n",
    "    use the same seed for image_datagen and mask_datagen to ensure the transformation for image and mask is the same\n",
    "    if you want to visualize the results of generator, set save_to_dir = \"your path\"\n",
    "    '''\n",
    "    image_datagen = ImageDataGenerator(**aug_dict)\n",
    "    mask_datagen = ImageDataGenerator(**aug_dict)\n",
    "    image_generator = image_datagen.flow_from_directory(\n",
    "        train_path,\n",
    "        classes = [image_folder],\n",
    "        class_mode = None,\n",
    "        color_mode = image_color_mode,\n",
    "        target_size = target_size,\n",
    "        batch_size = batch_size,\n",
    "        save_to_dir = save_to_dir,\n",
    "        save_prefix  = image_save_prefix,\n",
    "        seed = seed)\n",
    "    mask_generator = mask_datagen.flow_from_directory(\n",
    "        train_path,\n",
    "        classes = [mask_folder],\n",
    "        class_mode = None,\n",
    "        color_mode = mask_color_mode,\n",
    "        target_size = target_size,\n",
    "        batch_size = batch_size,\n",
    "        save_to_dir = save_to_dir,\n",
    "        save_prefix  = mask_save_prefix,\n",
    "        seed = seed)\n",
    "    train_generator = zip(image_generator, mask_generator)\n",
    "    for (img,mask) in train_generator:\n",
    "        img,mask = normalizeData_rgb(img,mask)\n",
    "        yield (img,mask)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Define UNet Network"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def UnetModel():\n",
    "    inputs = Input((img_rows, img_cols,1))\n",
    "    conv1 = Conv2D(32, (3, 3), activation=\"relu\", padding=\"same\")(inputs)\n",
    "    conv1 = Conv2D(32, (3, 3), activation=\"relu\", padding=\"same\")(conv1)\n",
    "    pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)\n",
    "\n",
    "    conv2 = Conv2D(64, (3, 3), activation=\"relu\", padding=\"same\")(pool1)\n",
    "    conv2 = Conv2D(64, (3, 3), activation=\"relu\", padding=\"same\")(conv2)\n",
    "    pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)\n",
    "\n",
    "    conv3 = Conv2D(128, (3, 3), activation=\"relu\", padding=\"same\")(pool2)\n",
    "    conv3 = Conv2D(128, (3, 3), activation=\"relu\", padding=\"same\")(conv3)\n",
    "    pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)\n",
    "\n",
    "    conv4 = Conv2D(256, (3, 3), activation=\"relu\", padding=\"same\")(pool3)\n",
    "    conv4 = Conv2D(256, (3, 3), activation=\"relu\", padding=\"same\")(conv4)\n",
    "    pool4 = MaxPooling2D(pool_size=(2, 2))(conv4)\n",
    "\n",
    "    conv5 = Conv2D(512, (3, 3), activation=\"relu\", padding=\"same\")(pool4)\n",
    "    conv5 = Conv2D(512, (3, 3), activation=\"relu\", padding=\"same\")(conv5)\n",
    "\n",
    "    up6 = concatenate([UpSampling2D(size=(2, 2))(conv5), conv4], axis=3)\n",
    "    conv6 = Conv2D(256, (3, 3), activation=\"relu\", padding=\"same\")(up6)\n",
    "    conv6 = Conv2D(256, (3, 3), activation=\"relu\", padding=\"same\")(conv6)\n",
    "\n",
    "    up7 = concatenate([UpSampling2D(size=(2, 2))(conv6), conv3], axis=3)\n",
    "    conv7 = Conv2D(128, (3, 3), activation=\"relu\", padding=\"same\")(up7)\n",
    "    conv7 = Conv2D(128, (3, 3), activation=\"relu\", padding=\"same\")(conv7)\n",
    "\n",
    "    up8 = concatenate([UpSampling2D(size=(2, 2))(conv7), conv2], axis=3)\n",
    "    conv8 = Conv2D(64, (3, 3), activation=\"relu\", padding=\"same\")(up8)\n",
    "    conv8 = Conv2D(64, (3, 3), activation=\"relu\", padding=\"same\")(conv8)\n",
    "\n",
    "    up9 = concatenate([UpSampling2D(size=(2, 2))(conv8), conv1], axis=3)\n",
    "    conv9 = Conv2D(32, (3, 3), activation=\"relu\", padding=\"same\")(up9)\n",
    "    conv9 = Conv2D(32, (3, 3), activation=\"relu\", padding=\"same\")(conv9)\n",
    "\n",
    "    conv10 = Conv2D(1, (1, 1), activation='sigmoid')(conv9)\n",
    "\n",
    "    model = Model(input=inputs, output=conv10)\n",
    "\n",
    "    model.compile(optimizer=Adam(lr=1e-5), loss=jaccard_coef_loss, metrics=[jaccard_coef])\n",
    "\n",
    "    return model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def UnetLeakyModel():\n",
    "    inputs = Input((img_rows, img_cols,3))\n",
    "    conv1 = Conv2D(32, (3, 3), padding=\"same\")(inputs)\n",
    "    acti1 = LeakyReLU(alpha=0.001)(conv1)\n",
    "    conv1 = Conv2D(32, (3, 3), padding=\"same\")(acti1)\n",
    "    acti1 = LeakyReLU(alpha=0.001)(conv1)\n",
    "    pool1 = MaxPooling2D(pool_size=(2, 2))(acti1)\n",
    "\n",
    "    conv2 = Conv2D(64, (3, 3), padding=\"same\")(pool1)\n",
    "    acti2 = LeakyReLU(alpha=0.001)(conv2)\n",
    "    conv2 = Conv2D(64, (3, 3), padding=\"same\")(acti2)\n",
    "    acti2 = LeakyReLU(alpha=0.001)(conv2)\n",
    "    pool2 = MaxPooling2D(pool_size=(2, 2))(acti2)\n",
    "\n",
    "    conv3 = Conv2D(128, (3, 3), padding=\"same\")(pool2)\n",
    "    acti3 = LeakyReLU(alpha=0.001)(conv3)\n",
    "    conv3 = Conv2D(128, (3, 3), padding=\"same\")(acti3)\n",
    "    acti3 = LeakyReLU(alpha=0.001)(conv3)\n",
    "    pool3 = MaxPooling2D(pool_size=(2, 2))(acti3)\n",
    "\n",
    "    conv4 = Conv2D(256, (3, 3), padding=\"same\")(pool3)\n",
    "    acti4 = LeakyReLU(alpha=0.001)(conv4)\n",
    "    conv4 = Conv2D(256, (3, 3), padding=\"same\")(acti4)\n",
    "    acti4 = LeakyReLU(alpha=0.001)(conv4)\n",
    "    pool4 = MaxPooling2D(pool_size=(2, 2))(acti4)\n",
    "\n",
    "    conv5 = Conv2D(512, (3, 3), padding=\"same\")(pool4)\n",
    "    acti5 = LeakyReLU(alpha=0.001)(conv5)\n",
    "    conv5 = Conv2D(512, (3, 3), padding=\"same\")(acti5)\n",
    "    acti5 = LeakyReLU(alpha=0.001)(conv5)\n",
    "    \n",
    "    up6 = concatenate([UpSampling2D(size=(2, 2))(acti5), acti4], axis=3)\n",
    "    conv6 = Conv2D(256, (3, 3), padding=\"same\")(up6)\n",
    "    acti6 = LeakyReLU(alpha=0.001)(conv6)\n",
    "    conv6 = Conv2D(256, (3, 3), padding=\"same\")(acti6)\n",
    "    acti6 = LeakyReLU(alpha=0.001)(conv6)\n",
    "\n",
    "    up7 = concatenate([UpSampling2D(size=(2, 2))(acti6), acti3], axis=3)\n",
    "    conv7 = Conv2D(128, (3, 3), padding=\"same\")(up7)\n",
    "    acti7 = LeakyReLU(alpha=0.001)(conv7)\n",
    "    conv7 = Conv2D(128, (3, 3), padding=\"same\")(acti7)\n",
    "    acti7 = LeakyReLU(alpha=0.001)(conv7)\n",
    "\n",
    "    up8 = concatenate([UpSampling2D(size=(2, 2))(acti7), acti2], axis=3)\n",
    "    conv8 = Conv2D(64, (3, 3), padding=\"same\")(up8)\n",
    "    acti8 = LeakyReLU(alpha=0.001)(conv8)\n",
    "    conv8 = Conv2D(64, (3, 3), padding=\"same\")(acti8)\n",
    "    acti8 = LeakyReLU(alpha=0.001)(conv8)\n",
    "\n",
    "    up9 = concatenate([UpSampling2D(size=(2, 2))(acti8), acti1], axis=3)\n",
    "    conv9 = Conv2D(32, (3, 3), padding=\"same\")(up9)\n",
    "    acti9 = LeakyReLU(alpha=0.001)(conv9)\n",
    "    conv9 = Conv2D(32, (3, 3), padding=\"same\")(acti9)\n",
    "    acti9 = LeakyReLU(alpha=0.001)(conv9)\n",
    "\n",
    "    conv10 = Conv2D(1, (1, 1), activation='sigmoid')(acti9)\n",
    "\n",
    "    model = Model(input=inputs, output=conv10)\n",
    "\n",
    "    model.compile(optimizer=Adam(lr=5e-5), loss=jaccard_coef_loss, metrics=[jaccard_coef])\n",
    "\n",
    "    return model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def LeakyUnetModelBig():\n",
    "    inputs = Input((img_rows, img_cols,1))\n",
    "    conv1 = Conv2D(32, (3, 3), padding=\"same\")(inputs)\n",
    "    acti1 = LeakyReLU(alpha=0.001)(conv1)\n",
    "    conv1 = Conv2D(32, (3, 3), padding=\"same\")(acti1)\n",
    "    acti1 = LeakyReLU(alpha=0.001)(conv1)\n",
    "    pool1 = MaxPooling2D(pool_size=(2, 2))(acti1)\n",
    "\n",
    "    conv2 = Conv2D(64, (3, 3), padding=\"same\")(pool1)\n",
    "    acti2 = LeakyReLU(alpha=0.001)(conv2)\n",
    "    conv2 = Conv2D(64, (3, 3), padding=\"same\")(acti2)\n",
    "    acti2 = LeakyReLU(alpha=0.001)(conv2)\n",
    "    pool2 = MaxPooling2D(pool_size=(2, 2))(acti2)\n",
    "\n",
    "    conv3 = Conv2D(128, (3, 3), padding=\"same\")(pool2)\n",
    "    acti3 = LeakyReLU(alpha=0.001)(conv3)\n",
    "    conv3 = Conv2D(128, (3, 3), padding=\"same\")(acti3)\n",
    "    acti3 = LeakyReLU(alpha=0.001)(conv3)\n",
    "    pool3 = MaxPooling2D(pool_size=(2, 2))(acti3)\n",
    "\n",
    "    conv4 = Conv2D(256, (3, 3), padding=\"same\")(pool3)\n",
    "    acti4 = LeakyReLU(alpha=0.001)(conv4)\n",
    "    conv4 = Conv2D(256, (3, 3), padding=\"same\")(acti4)\n",
    "    acti4 = LeakyReLU(alpha=0.001)(conv4)\n",
    "    pool4 = MaxPooling2D(pool_size=(2, 2))(acti4)\n",
    "\n",
    "    conv5 = Conv2D(512, (3, 3), padding=\"same\")(pool4)\n",
    "    acti5 = LeakyReLU(alpha=0.001)(conv5)\n",
    "    conv5 = Conv2D(512, (3, 3), padding=\"same\")(acti5)\n",
    "    acti5 = LeakyReLU(alpha=0.001)(conv5)\n",
    "    \n",
    "    conv6 = Conv2D(512, (3, 3), padding=\"same\")(acti5)\n",
    "    acti6 = LeakyReLU(alpha=0.001)(conv6)\n",
    "    conv6 = Conv2D(512, (3, 3), padding=\"same\")(acti6)\n",
    "    acti6 = LeakyReLU(alpha=0.001)(conv6)\n",
    "    \n",
    "    right_up1 = concatenate([UpSampling2D(size=(2, 2))(acti6), acti4], axis=3)\n",
    "    right_conv1 = Conv2D(256, (3, 3), padding=\"same\")(right_up1)\n",
    "    right_acti1 = LeakyReLU(alpha=0.001)(right_conv1)\n",
    "    right_conv1 = Conv2D(256, (3, 3), padding=\"same\")(right_acti1)\n",
    "    right_acti1 = LeakyReLU(alpha=0.001)(right_conv1)\n",
    "\n",
    "    right_up2 = concatenate([UpSampling2D(size=(2, 2))(right_acti1), acti3], axis=3)\n",
    "    right_conv2 = Conv2D(128, (3, 3), padding=\"same\")(right_up2)\n",
    "    right_acti2 = LeakyReLU(alpha=0.001)(right_conv2)\n",
    "    right_conv2 = Conv2D(128, (3, 3), padding=\"same\")(right_acti2)\n",
    "    right_acti2 = LeakyReLU(alpha=0.001)(right_conv2)\n",
    "\n",
    "    right_up3 = concatenate([UpSampling2D(size=(2, 2))(right_acti2), acti2], axis=3)\n",
    "    right_conv3 = Conv2D(64, (3, 3), padding=\"same\")(right_up3)\n",
    "    right_acti3 = LeakyReLU(alpha=0.001)(right_conv3)\n",
    "    right_conv3 = Conv2D(64, (3, 3), padding=\"same\")(right_acti3)\n",
    "    right_acti3 = LeakyReLU(alpha=0.001)(right_conv3)\n",
    "\n",
    "    right_up4 = concatenate([UpSampling2D(size=(2, 2))(right_conv3), acti1], axis=3)\n",
    "    right_conv4 = Conv2D(32, (3, 3), padding=\"same\")(right_up4)\n",
    "    right_acti4 = LeakyReLU(alpha=0.001)(right_conv4)\n",
    "    right_conv4 = Conv2D(32, (3, 3), padding=\"same\")(right_acti4)\n",
    "    right_acti4 = LeakyReLU(alpha=0.001)(right_conv4)\n",
    "\n",
    "    output = Conv2D(1, (1, 1), activation='sigmoid')(right_acti4)\n",
    "\n",
    "    model = Model(input=inputs, output=output)\n",
    "\n",
    "    model.compile(optimizer=Adam(lr=3e-5), loss=jaccard_coef_loss, metrics=[jaccard_coef])\n",
    "\n",
    "    return model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def FullUnetModel():\n",
    "    inputs = Input((img_rows, img_cols,1))\n",
    "    conv1 = Conv2D(64, (3, 3), activation=\"relu\", padding=\"same\")(inputs)\n",
    "    conv1 = Conv2D(64, (3, 3), activation=\"relu\", padding=\"same\")(conv1)\n",
    "    pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)\n",
    "\n",
    "    conv2 = Conv2D(128, (3, 3), activation=\"relu\", padding=\"same\")(pool1)\n",
    "    conv2 = Conv2D(128, (3, 3), activation=\"relu\", padding=\"same\")(conv2)\n",
    "    pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)\n",
    "\n",
    "    conv3 = Conv2D(256, (3, 3), activation=\"relu\", padding=\"same\")(pool2)\n",
    "    conv3 = Conv2D(256, (3, 3), activation=\"relu\", padding=\"same\")(conv3)\n",
    "    pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)\n",
    "\n",
    "    conv4 = Conv2D(512, (3, 3), activation=\"relu\", padding=\"same\")(pool3)\n",
    "    conv4 = Conv2D(512, (3, 3), activation=\"relu\", padding=\"same\")(conv4)\n",
    "    pool4 = MaxPooling2D(pool_size=(2, 2))(conv4)\n",
    "\n",
    "    conv5 = Conv2D(1024, (3, 3), activation=\"relu\", padding=\"same\")(pool4)\n",
    "    conv5 = Conv2D(1024, (3, 3), activation=\"relu\", padding=\"same\")(conv5)\n",
    "\n",
    "    up6 = concatenate([UpSampling2D(size=(2, 2))(conv5), conv4], axis=3)\n",
    "    conv6 = Conv2D(512, (3, 3), activation=\"relu\", padding=\"same\")(up6)\n",
    "    conv6 = Conv2D(512, (3, 3), activation=\"relu\", padding=\"same\")(conv6)\n",
    "\n",
    "    up7 = concatenate([UpSampling2D(size=(2, 2))(conv6), conv3], axis=3)\n",
    "    conv7 = Conv2D(256, (3, 3), activation=\"relu\", padding=\"same\")(up7)\n",
    "    conv7 = Conv2D(256, (3, 3), activation=\"relu\", padding=\"same\")(conv7)\n",
    "\n",
    "    up8 = concatenate([UpSampling2D(size=(2, 2))(conv7), conv2], axis=3)\n",
    "    conv8 = Conv2D(128, (3, 3), activation=\"relu\", padding=\"same\")(up8)\n",
    "    conv8 = Conv2D(128, (3, 3), activation=\"relu\", padding=\"same\")(conv8)\n",
    "\n",
    "    up9 = concatenate([UpSampling2D(size=(2, 2))(conv8), conv1], axis=3)\n",
    "    conv9 = Conv2D(64, (3, 3), activation=\"relu\", padding=\"same\")(up9)\n",
    "    conv9 = Conv2D(64, (3, 3), activation=\"relu\", padding=\"same\")(conv9)\n",
    "\n",
    "    conv10 = Conv2D(1, (1, 1), activation='sigmoid')(conv9)\n",
    "\n",
    "    model = Model(input=inputs, output=conv10)\n",
    "\n",
    "    model.compile(optimizer=Adam(lr=1e-4), loss=jaccard_coef_loss, metrics=[jaccard_coef])\n",
    "\n",
    "    return model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\li_ni\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:58: UserWarning: Update your `Model` call to the Keras 2 API: `Model(inputs=Tensor(\"in..., outputs=Tensor(\"co...)`\n"
     ]
    },
    {
     "ename": "TypeError",
     "evalue": "Using a `tf.Tensor` as a Python `bool` is not allowed. Use `if t is not None:` instead of `if t:` to test if a tensor is defined, and use TensorFlow ops such as tf.cond to execute subgraphs conditioned on the value of a tensor.",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-14-6a53066bf44a>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m     21\u001b[0m \u001b[1;31m#model = FullUnetModel()\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     22\u001b[0m \u001b[1;31m#model = UnetModel()\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 23\u001b[1;33m \u001b[0mmodel\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mUnetLeakyModel\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32m<ipython-input-9-011ca8f987f4>\u001b[0m in \u001b[0;36mUnetLeakyModel\u001b[1;34m()\u001b[0m\n\u001b[0;32m     58\u001b[0m     \u001b[0mmodel\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mModel\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minput\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0minputs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0moutput\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mconv10\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     59\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 60\u001b[1;33m     \u001b[0mmodel\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcompile\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moptimizer\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mAdam\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlr\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m5e-5\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mloss\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mjaccard_coef_loss\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmetrics\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mjaccard_coef\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     61\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     62\u001b[0m     \u001b[1;32mreturn\u001b[0m \u001b[0mmodel\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m~\\Anaconda3\\lib\\site-packages\\keras\\engine\\training.py\u001b[0m in \u001b[0;36mcompile\u001b[1;34m(self, optimizer, loss, metrics, loss_weights, sample_weight_mode, weighted_metrics, target_tensors, **kwargs)\u001b[0m\n\u001b[0;32m    340\u001b[0m                 \u001b[1;32mwith\u001b[0m \u001b[0mK\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mname_scope\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0moutput_names\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;34m'_loss'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    341\u001b[0m                     output_loss = weighted_loss(y_true, y_pred,\n\u001b[1;32m--> 342\u001b[1;33m                                                 sample_weight, mask)\n\u001b[0m\u001b[0;32m    343\u001b[0m                 \u001b[1;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0moutputs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m>\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    344\u001b[0m                     \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmetrics_tensors\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moutput_loss\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m~\\Anaconda3\\lib\\site-packages\\keras\\engine\\training_utils.py\u001b[0m in \u001b[0;36mweighted\u001b[1;34m(y_true, y_pred, weights, mask)\u001b[0m\n\u001b[0;32m    402\u001b[0m         \"\"\"\n\u001b[0;32m    403\u001b[0m         \u001b[1;31m# score_array has ndim >= 2\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 404\u001b[1;33m         \u001b[0mscore_array\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mfn\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0my_true\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my_pred\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    405\u001b[0m         \u001b[1;32mif\u001b[0m \u001b[0mmask\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    406\u001b[0m             \u001b[1;31m# Cast the mask to floatX to avoid float64 upcasting in Theano\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m<ipython-input-13-50b11c8f7a04>\u001b[0m in \u001b[0;36mjaccard_coef_loss\u001b[1;34m(y_true, y_pred)\u001b[0m\n\u001b[0;32m     13\u001b[0m     \u001b[0mintersection\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mK\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msum\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0my_true_f\u001b[0m \u001b[1;33m*\u001b[0m \u001b[0my_pred_f\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     14\u001b[0m     \u001b[0mj\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m-\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mintersection\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0msmooth\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m/\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mK\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msum\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0my_true_f\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mK\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msum\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0my_pred_f\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m-\u001b[0m \u001b[0mintersection\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0msmooth\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 15\u001b[1;33m     \u001b[1;32mif\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mj\u001b[0m \u001b[1;33m>\u001b[0m \u001b[1;36m0.65\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     16\u001b[0m         \u001b[0mj\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mj\u001b[0m \u001b[1;33m-\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     17\u001b[0m     \u001b[1;32mreturn\u001b[0m \u001b[0mj\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m~\\Anaconda3\\lib\\site-packages\\tensorflow\\python\\framework\\ops.py\u001b[0m in \u001b[0;36m__bool__\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m    651\u001b[0m       \u001b[0;31m`\u001b[0m\u001b[0mTypeError\u001b[0m\u001b[0;31m`\u001b[0m\u001b[1;33m.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    652\u001b[0m     \"\"\"\n\u001b[1;32m--> 653\u001b[1;33m     raise TypeError(\"Using a `tf.Tensor` as a Python `bool` is not allowed. \"\n\u001b[0m\u001b[0;32m    654\u001b[0m                     \u001b[1;34m\"Use `if t is not None:` instead of `if t:` to test if a \"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    655\u001b[0m                     \u001b[1;34m\"tensor is defined, and use TensorFlow ops such as \"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mTypeError\u001b[0m: Using a `tf.Tensor` as a Python `bool` is not allowed. Use `if t is not None:` instead of `if t:` to test if a tensor is defined, and use TensorFlow ops such as tf.cond to execute subgraphs conditioned on the value of a tensor."
     ]
    }
   ],
   "source": [
    "#Training data generation\n",
    "data_gen_args = dict(\n",
    "#    samplewise_center = True,\n",
    "#    samplewise_std_normalization = True,\n",
    "    rotation_range=180,\n",
    "    width_shift_range=0.05,\n",
    "    height_shift_range=0.05,\n",
    "    shear_range=0.05,\n",
    "    zoom_range=0.05,\n",
    "    horizontal_flip=True,\n",
    "    vertical_flip = True,\n",
    "    fill_mode='nearest')\n",
    "\n",
    "#Validation data generation\n",
    "data_val_gen_args = dict(\n",
    "    #samplewise_center = True,\n",
    "    #samplewise_std_normalization = True\n",
    "    )\n",
    "\n",
    "#Create UNet Model\n",
    "#model = FullUnetModel()\n",
    "#model = UnetModel()\n",
    "model = UnetLeakyModel()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Setup generator\n",
    "batch_size = 3\n",
    "\n",
    "myGene = trainGenerator(batch_size,'data/train','images','masks',data_gen_args)\n",
    "myValGene = validationGenerator(batch_size,'data/val','images','masks',data_val_gen_args)\n",
    "\n",
    "#Setup Checkpoint to only capture best estimate\n",
    "model_checkpoint = ModelCheckpoint('unet_lesion.hdf5', monitor='loss',verbose=1, save_best_only=True)\n",
    "\n",
    "#Enable tensorboard\n",
    "tensorBoard = TensorBoard(\n",
    "    log_dir='./logs', \n",
    "    histogram_freq=0, \n",
    "    batch_size=batch_size, \n",
    "    write_graph=True, \n",
    "    write_grads=False, \n",
    "    write_images=True, \n",
    "    embeddings_freq=0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/200\n",
      "Found 519 images belonging to 1 classes.\n",
      "Found 1555 images belonging to 1 classes.\n",
      "Found 519 images belonging to 1 classes.\n",
      "Found 1555 images belonging to 1 classes.\n",
      "600/600 [==============================] - 580s 967ms/step - loss: -0.5096 - jaccard_coef: 0.5096 - val_loss: -0.6585 - val_jaccard_coef: 0.6585\n",
      "\n",
      "Epoch 00001: loss improved from inf to -0.50956, saving model to unet_lesion.hdf5\n",
      "Epoch 2/200\n",
      "600/600 [==============================] - 564s 940ms/step - loss: -0.6369 - jaccard_coef: 0.6369 - val_loss: -0.7029 - val_jaccard_coef: 0.7029\n",
      "\n",
      "Epoch 00002: loss improved from -0.50956 to -0.63674, saving model to unet_lesion.hdf5\n",
      "Epoch 3/200\n",
      "600/600 [==============================] - 563s 939ms/step - loss: -0.6608 - jaccard_coef: 0.6608 - val_loss: -0.7091 - val_jaccard_coef: 0.7091\n",
      "\n",
      "Epoch 00003: loss improved from -0.63674 to -0.66082, saving model to unet_lesion.hdf5\n",
      "Epoch 4/200\n",
      "600/600 [==============================] - 559s 932ms/step - loss: -0.6874 - jaccard_coef: 0.6874 - val_loss: -0.7053 - val_jaccard_coef: 0.7053\n",
      "\n",
      "Epoch 00004: loss improved from -0.66082 to -0.68730, saving model to unet_lesion.hdf5\n",
      "Epoch 5/200\n",
      "600/600 [==============================] - 575s 958ms/step - loss: -0.6906 - jaccard_coef: 0.6906 - val_loss: -0.7425 - val_jaccard_coef: 0.7425\n",
      "\n",
      "Epoch 00005: loss improved from -0.68730 to -0.69063, saving model to unet_lesion.hdf5\n",
      "Epoch 6/200\n",
      "600/600 [==============================] - 570s 950ms/step - loss: -0.6976 - jaccard_coef: 0.6976 - val_loss: -0.7250 - val_jaccard_coef: 0.7250\n",
      "\n",
      "Epoch 00006: loss improved from -0.69063 to -0.69747, saving model to unet_lesion.hdf5\n",
      "Epoch 7/200\n",
      "600/600 [==============================] - 573s 955ms/step - loss: -0.7057 - jaccard_coef: 0.7057 - val_loss: -0.7195 - val_jaccard_coef: 0.7195\n",
      "\n",
      "Epoch 00007: loss improved from -0.69747 to -0.70551, saving model to unet_lesion.hdf5\n",
      "Epoch 8/200\n",
      "600/600 [==============================] - 558s 930ms/step - loss: -0.7166 - jaccard_coef: 0.7166 - val_loss: -0.7340 - val_jaccard_coef: 0.7340\n",
      "\n",
      "Epoch 00008: loss improved from -0.70551 to -0.71683, saving model to unet_lesion.hdf5\n",
      "Epoch 9/200\n",
      "600/600 [==============================] - 567s 944ms/step - loss: -0.7111 - jaccard_coef: 0.7111 - val_loss: -0.6903 - val_jaccard_coef: 0.6903\n",
      "\n",
      "Epoch 00009: loss did not improve from -0.71683\n",
      "Epoch 10/200\n",
      "600/600 [==============================] - 573s 955ms/step - loss: -0.7181 - jaccard_coef: 0.7181 - val_loss: -0.7340 - val_jaccard_coef: 0.7340\n",
      "\n",
      "Epoch 00010: loss improved from -0.71683 to -0.71794, saving model to unet_lesion.hdf5\n",
      "Epoch 11/200\n",
      "600/600 [==============================] - 561s 935ms/step - loss: -0.7163 - jaccard_coef: 0.7163 - val_loss: -0.7086 - val_jaccard_coef: 0.7086\n",
      "\n",
      "Epoch 00011: loss did not improve from -0.71794\n",
      "Epoch 12/200\n",
      "600/600 [==============================] - 564s 940ms/step - loss: -0.7307 - jaccard_coef: 0.7307 - val_loss: -0.7379 - val_jaccard_coef: 0.7379\n",
      "\n",
      "Epoch 00012: loss improved from -0.71794 to -0.73092, saving model to unet_lesion.hdf5\n",
      "Epoch 13/200\n",
      "600/600 [==============================] - 559s 931ms/step - loss: -0.7331 - jaccard_coef: 0.7331 - val_loss: -0.7483 - val_jaccard_coef: 0.7483\n",
      "\n",
      "Epoch 00013: loss improved from -0.73092 to -0.73285, saving model to unet_lesion.hdf5\n",
      "Epoch 14/200\n",
      "600/600 [==============================] - 562s 937ms/step - loss: -0.7300 - jaccard_coef: 0.7300 - val_loss: -0.7469 - val_jaccard_coef: 0.7469\n",
      "\n",
      "Epoch 00014: loss did not improve from -0.73285\n",
      "Epoch 15/200\n",
      "600/600 [==============================] - 563s 939ms/step - loss: -0.7484 - jaccard_coef: 0.7484 - val_loss: -0.7178 - val_jaccard_coef: 0.7178\n",
      "\n",
      "Epoch 00015: loss improved from -0.73285 to -0.74836, saving model to unet_lesion.hdf5\n",
      "Epoch 16/200\n",
      "600/600 [==============================] - 568s 946ms/step - loss: -0.7414 - jaccard_coef: 0.7414 - val_loss: -0.7555 - val_jaccard_coef: 0.7555\n",
      "\n",
      "Epoch 00016: loss did not improve from -0.74836\n",
      "Epoch 17/200\n",
      "600/600 [==============================] - 567s 944ms/step - loss: -0.7408 - jaccard_coef: 0.7408 - val_loss: -0.7605 - val_jaccard_coef: 0.7605\n",
      "\n",
      "Epoch 00017: loss did not improve from -0.74836\n",
      "Epoch 18/200\n",
      "600/600 [==============================] - 553s 921ms/step - loss: -0.7505 - jaccard_coef: 0.7505 - val_loss: -0.7739 - val_jaccard_coef: 0.7739\n",
      "\n",
      "Epoch 00018: loss improved from -0.74836 to -0.75035, saving model to unet_lesion.hdf5\n",
      "Epoch 19/200\n",
      "600/600 [==============================] - 585s 974ms/step - loss: -0.7467 - jaccard_coef: 0.7467 - val_loss: -0.7456 - val_jaccard_coef: 0.7456\n",
      "\n",
      "Epoch 00019: loss did not improve from -0.75035\n",
      "Epoch 20/200\n",
      "600/600 [==============================] - 571s 952ms/step - loss: -0.7379 - jaccard_coef: 0.7379 - val_loss: -0.7560 - val_jaccard_coef: 0.7560\n",
      "\n",
      "Epoch 00020: loss did not improve from -0.75035\n",
      "Epoch 21/200\n",
      "600/600 [==============================] - 565s 942ms/step - loss: -0.7425 - jaccard_coef: 0.7425 - val_loss: -0.7692 - val_jaccard_coef: 0.7692\n",
      "\n",
      "Epoch 00021: loss did not improve from -0.75035\n",
      "Epoch 22/200\n",
      "600/600 [==============================] - 554s 923ms/step - loss: -0.7545 - jaccard_coef: 0.7545 - val_loss: -0.7302 - val_jaccard_coef: 0.7302\n",
      "\n",
      "Epoch 00022: loss improved from -0.75035 to -0.75437, saving model to unet_lesion.hdf5\n",
      "Epoch 23/200\n",
      "600/600 [==============================] - 581s 969ms/step - loss: -0.7489 - jaccard_coef: 0.7489 - val_loss: -0.7560 - val_jaccard_coef: 0.7560\n",
      "\n",
      "Epoch 00023: loss did not improve from -0.75437\n",
      "Epoch 24/200\n",
      "600/600 [==============================] - 557s 928ms/step - loss: -0.7582 - jaccard_coef: 0.7582 - val_loss: -0.7563 - val_jaccard_coef: 0.7563\n",
      "\n",
      "Epoch 00024: loss improved from -0.75437 to -0.75806, saving model to unet_lesion.hdf5\n",
      "Epoch 25/200\n",
      "600/600 [==============================] - 559s 932ms/step - loss: -0.7487 - jaccard_coef: 0.7487 - val_loss: -0.7408 - val_jaccard_coef: 0.7408\n",
      "\n",
      "Epoch 00025: loss did not improve from -0.75806\n",
      "Epoch 26/200\n",
      "600/600 [==============================] - 568s 947ms/step - loss: -0.7565 - jaccard_coef: 0.7565 - val_loss: -0.7568 - val_jaccard_coef: 0.7568\n",
      "\n",
      "Epoch 00026: loss did not improve from -0.75806\n",
      "Epoch 27/200\n",
      "600/600 [==============================] - 567s 945ms/step - loss: -0.7609 - jaccard_coef: 0.7609 - val_loss: -0.7636 - val_jaccard_coef: 0.7636\n",
      "\n",
      "Epoch 00027: loss improved from -0.75806 to -0.76073, saving model to unet_lesion.hdf5\n",
      "Epoch 28/200\n",
      "600/600 [==============================] - 582s 970ms/step - loss: -0.7560 - jaccard_coef: 0.7560 - val_loss: -0.7486 - val_jaccard_coef: 0.7486\n",
      "\n",
      "Epoch 00028: loss did not improve from -0.76073\n",
      "Epoch 29/200\n",
      "600/600 [==============================] - 589s 982ms/step - loss: -0.7534 - jaccard_coef: 0.7534 - val_loss: -0.7591 - val_jaccard_coef: 0.7591\n",
      "\n",
      "Epoch 00029: loss did not improve from -0.76073\n",
      "Epoch 30/200\n",
      "600/600 [==============================] - 581s 969ms/step - loss: -0.7640 - jaccard_coef: 0.7640 - val_loss: -0.7898 - val_jaccard_coef: 0.7898\n",
      "\n",
      "Epoch 00030: loss improved from -0.76073 to -0.76393, saving model to unet_lesion.hdf5\n",
      "Epoch 31/200\n",
      "600/600 [==============================] - 576s 961ms/step - loss: -0.7544 - jaccard_coef: 0.7544 - val_loss: -0.7660 - val_jaccard_coef: 0.7660\n",
      "\n",
      "Epoch 00031: loss did not improve from -0.76393\n",
      "Epoch 32/200\n",
      "600/600 [==============================] - 587s 979ms/step - loss: -0.7642 - jaccard_coef: 0.7642 - val_loss: -0.7635 - val_jaccard_coef: 0.7635\n",
      "\n",
      "Epoch 00032: loss improved from -0.76393 to -0.76461, saving model to unet_lesion.hdf5\n",
      "Epoch 33/200\n",
      "600/600 [==============================] - 586s 977ms/step - loss: -0.7575 - jaccard_coef: 0.7575 - val_loss: -0.7697 - val_jaccard_coef: 0.7697\n",
      "\n",
      "Epoch 00033: loss did not improve from -0.76461\n",
      "Epoch 34/200\n",
      "600/600 [==============================] - 581s 968ms/step - loss: -0.7699 - jaccard_coef: 0.7699 - val_loss: -0.7733 - val_jaccard_coef: 0.7733\n",
      "\n",
      "Epoch 00034: loss improved from -0.76461 to -0.76970, saving model to unet_lesion.hdf5\n",
      "Epoch 35/200\n",
      "600/600 [==============================] - 584s 973ms/step - loss: -0.7616 - jaccard_coef: 0.7616 - val_loss: -0.7605 - val_jaccard_coef: 0.7605\n",
      "\n",
      "Epoch 00035: loss did not improve from -0.76970\n",
      "Epoch 36/200\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "600/600 [==============================] - 571s 952ms/step - loss: -0.7685 - jaccard_coef: 0.7685 - val_loss: -0.7709 - val_jaccard_coef: 0.7709\n",
      "\n",
      "Epoch 00036: loss did not improve from -0.76970\n",
      "Epoch 37/200\n",
      "600/600 [==============================] - 585s 976ms/step - loss: -0.7609 - jaccard_coef: 0.7609 - val_loss: -0.7612 - val_jaccard_coef: 0.7612\n",
      "\n",
      "Epoch 00037: loss did not improve from -0.76970\n",
      "Epoch 38/200\n",
      "600/600 [==============================] - 581s 969ms/step - loss: -0.7660 - jaccard_coef: 0.7660 - val_loss: -0.7747 - val_jaccard_coef: 0.7747\n",
      "\n",
      "Epoch 00038: loss did not improve from -0.76970\n",
      "Epoch 39/200\n",
      "600/600 [==============================] - 580s 967ms/step - loss: -0.7645 - jaccard_coef: 0.7645 - val_loss: -0.7830 - val_jaccard_coef: 0.7830\n",
      "\n",
      "Epoch 00039: loss did not improve from -0.76970\n",
      "Epoch 40/200\n",
      "600/600 [==============================] - 576s 959ms/step - loss: -0.7739 - jaccard_coef: 0.7739 - val_loss: -0.7708 - val_jaccard_coef: 0.7708\n",
      "\n",
      "Epoch 00040: loss improved from -0.76970 to -0.77380, saving model to unet_lesion.hdf5\n",
      "Epoch 41/200\n",
      "600/600 [==============================] - 584s 974ms/step - loss: -0.7663 - jaccard_coef: 0.7663 - val_loss: -0.7595 - val_jaccard_coef: 0.7595\n",
      "\n",
      "Epoch 00041: loss did not improve from -0.77380\n",
      "Epoch 42/200\n",
      "600/600 [==============================] - 584s 973ms/step - loss: -0.7662 - jaccard_coef: 0.7662 - val_loss: -0.7616 - val_jaccard_coef: 0.7616\n",
      "\n",
      "Epoch 00042: loss did not improve from -0.77380\n",
      "Epoch 43/200\n",
      "600/600 [==============================] - 583s 972ms/step - loss: -0.7637 - jaccard_coef: 0.7637 - val_loss: -0.7664 - val_jaccard_coef: 0.7664\n",
      "\n",
      "Epoch 00043: loss did not improve from -0.77380\n",
      "Epoch 44/200\n",
      "600/600 [==============================] - 605s 1s/step - loss: -0.7731 - jaccard_coef: 0.7731 - val_loss: -0.7733 - val_jaccard_coef: 0.7733\n",
      "\n",
      "Epoch 00044: loss did not improve from -0.77380\n",
      "Epoch 45/200\n",
      "600/600 [==============================] - 598s 997ms/step - loss: -0.7628 - jaccard_coef: 0.7628 - val_loss: -0.7698 - val_jaccard_coef: 0.7698\n",
      "\n",
      "Epoch 00045: loss did not improve from -0.77380\n",
      "Epoch 46/200\n",
      "600/600 [==============================] - 586s 976ms/step - loss: -0.7692 - jaccard_coef: 0.7692 - val_loss: -0.7683 - val_jaccard_coef: 0.7683\n",
      "\n",
      "Epoch 00046: loss did not improve from -0.77380\n",
      "Epoch 47/200\n",
      "600/600 [==============================] - 566s 944ms/step - loss: -0.7761 - jaccard_coef: 0.7761 - val_loss: -0.7602 - val_jaccard_coef: 0.7602\n",
      "\n",
      "Epoch 00047: loss improved from -0.77380 to -0.77612, saving model to unet_lesion.hdf5\n",
      "Epoch 48/200\n",
      "600/600 [==============================] - 585s 975ms/step - loss: -0.7664 - jaccard_coef: 0.7664 - val_loss: -0.7712 - val_jaccard_coef: 0.7712\n",
      "\n",
      "Epoch 00048: loss did not improve from -0.77612\n",
      "Epoch 49/200\n",
      "600/600 [==============================] - 563s 939ms/step - loss: -0.7685 - jaccard_coef: 0.7685 - val_loss: -0.7714 - val_jaccard_coef: 0.7714\n",
      "\n",
      "Epoch 00049: loss did not improve from -0.77612\n",
      "Epoch 50/200\n",
      "600/600 [==============================] - 583s 971ms/step - loss: -0.7800 - jaccard_coef: 0.7800 - val_loss: -0.7654 - val_jaccard_coef: 0.7654\n",
      "\n",
      "Epoch 00050: loss improved from -0.77612 to -0.78070, saving model to unet_lesion.hdf5\n",
      "Epoch 51/200\n",
      "600/600 [==============================] - 564s 940ms/step - loss: -0.7703 - jaccard_coef: 0.7703 - val_loss: -0.7538 - val_jaccard_coef: 0.7538\n",
      "\n",
      "Epoch 00051: loss did not improve from -0.78070\n",
      "Epoch 52/200\n",
      "600/600 [==============================] - 564s 940ms/step - loss: -0.7726 - jaccard_coef: 0.7726 - val_loss: -0.7689 - val_jaccard_coef: 0.7689\n",
      "\n",
      "Epoch 00052: loss did not improve from -0.78070\n",
      "Epoch 53/200\n",
      "600/600 [==============================] - 588s 980ms/step - loss: -0.7748 - jaccard_coef: 0.7748 - val_loss: -0.7765 - val_jaccard_coef: 0.7765\n",
      "\n",
      "Epoch 00053: loss did not improve from -0.78070\n",
      "Epoch 54/200\n",
      "600/600 [==============================] - 558s 930ms/step - loss: -0.7773 - jaccard_coef: 0.7773 - val_loss: -0.7662 - val_jaccard_coef: 0.7662\n",
      "\n",
      "Epoch 00054: loss did not improve from -0.78070\n",
      "Epoch 55/200\n",
      "600/600 [==============================] - 577s 962ms/step - loss: -0.7754 - jaccard_coef: 0.7754 - val_loss: -0.7741 - val_jaccard_coef: 0.7741\n",
      "\n",
      "Epoch 00055: loss did not improve from -0.78070\n",
      "Epoch 56/200\n",
      "600/600 [==============================] - 555s 925ms/step - loss: -0.7738 - jaccard_coef: 0.7738 - val_loss: -0.7769 - val_jaccard_coef: 0.7769\n",
      "\n",
      "Epoch 00056: loss did not improve from -0.78070\n",
      "Epoch 57/200\n",
      "600/600 [==============================] - 574s 957ms/step - loss: -0.7785 - jaccard_coef: 0.7785 - val_loss: -0.7887 - val_jaccard_coef: 0.7887\n",
      "\n",
      "Epoch 00057: loss did not improve from -0.78070\n",
      "Epoch 58/200\n",
      "600/600 [==============================] - 568s 947ms/step - loss: -0.7773 - jaccard_coef: 0.7773 - val_loss: -0.7874 - val_jaccard_coef: 0.7874\n",
      "\n",
      "Epoch 00058: loss did not improve from -0.78070\n",
      "Epoch 59/200\n",
      "600/600 [==============================] - 574s 956ms/step - loss: -0.7807 - jaccard_coef: 0.7807 - val_loss: -0.7862 - val_jaccard_coef: 0.7862\n",
      "\n",
      "Epoch 00059: loss did not improve from -0.78070\n",
      "Epoch 60/200\n",
      "600/600 [==============================] - 572s 954ms/step - loss: -0.7805 - jaccard_coef: 0.7805 - val_loss: -0.7752 - val_jaccard_coef: 0.7752\n",
      "\n",
      "Epoch 00060: loss improved from -0.78070 to -0.78083, saving model to unet_lesion.hdf5\n",
      "Epoch 61/200\n",
      "600/600 [==============================] - 587s 978ms/step - loss: -0.7800 - jaccard_coef: 0.7800 - val_loss: -0.7900 - val_jaccard_coef: 0.7900\n",
      "\n",
      "Epoch 00061: loss did not improve from -0.78083\n",
      "Epoch 62/200\n",
      "600/600 [==============================] - 561s 935ms/step - loss: -0.7865 - jaccard_coef: 0.7865 - val_loss: -0.7767 - val_jaccard_coef: 0.7767\n",
      "\n",
      "Epoch 00062: loss improved from -0.78083 to -0.78651, saving model to unet_lesion.hdf5\n",
      "Epoch 63/200\n",
      "600/600 [==============================] - 571s 951ms/step - loss: -0.7802 - jaccard_coef: 0.7802 - val_loss: -0.7608 - val_jaccard_coef: 0.7608\n",
      "\n",
      "Epoch 00063: loss did not improve from -0.78651\n",
      "Epoch 64/200\n",
      "600/600 [==============================] - 572s 954ms/step - loss: -0.7836 - jaccard_coef: 0.7836 - val_loss: -0.7783 - val_jaccard_coef: 0.7783\n",
      "\n",
      "Epoch 00064: loss did not improve from -0.78651\n",
      "Epoch 65/200\n",
      "600/600 [==============================] - 568s 946ms/step - loss: -0.7897 - jaccard_coef: 0.7897 - val_loss: -0.7882 - val_jaccard_coef: 0.7882\n",
      "\n",
      "Epoch 00065: loss improved from -0.78651 to -0.78960, saving model to unet_lesion.hdf5\n",
      "Epoch 66/200\n",
      "600/600 [==============================] - 574s 956ms/step - loss: -0.7809 - jaccard_coef: 0.7809 - val_loss: -0.7864 - val_jaccard_coef: 0.7864\n",
      "\n",
      "Epoch 00066: loss did not improve from -0.78960\n",
      "Epoch 67/200\n",
      "600/600 [==============================] - 579s 966ms/step - loss: -0.7871 - jaccard_coef: 0.7871 - val_loss: -0.7890 - val_jaccard_coef: 0.7890\n",
      "\n",
      "Epoch 00067: loss did not improve from -0.78960\n",
      "Epoch 68/200\n",
      "600/600 [==============================] - 568s 946ms/step - loss: -0.7819 - jaccard_coef: 0.7819 - val_loss: -0.7601 - val_jaccard_coef: 0.7601\n",
      "\n",
      "Epoch 00068: loss did not improve from -0.78960\n",
      "Epoch 69/200\n",
      "600/600 [==============================] - 568s 947ms/step - loss: -0.7809 - jaccard_coef: 0.7809 - val_loss: -0.7684 - val_jaccard_coef: 0.7684\n",
      "\n",
      "Epoch 00069: loss did not improve from -0.78960\n",
      "Epoch 70/200\n",
      "600/600 [==============================] - 576s 960ms/step - loss: -0.7839 - jaccard_coef: 0.7839 - val_loss: -0.7730 - val_jaccard_coef: 0.7730\n",
      "\n",
      "Epoch 00070: loss did not improve from -0.78960\n",
      "Epoch 71/200\n",
      "600/600 [==============================] - 571s 952ms/step - loss: -0.7835 - jaccard_coef: 0.7835 - val_loss: -0.7805 - val_jaccard_coef: 0.7805\n",
      "\n",
      "Epoch 00071: loss did not improve from -0.78960\n",
      "Epoch 72/200\n",
      "600/600 [==============================] - 575s 959ms/step - loss: -0.7835 - jaccard_coef: 0.7835 - val_loss: -0.7874 - val_jaccard_coef: 0.7874\n",
      "\n",
      "Epoch 00072: loss did not improve from -0.78960\n",
      "Epoch 73/200\n",
      "600/600 [==============================] - 560s 934ms/step - loss: -0.7884 - jaccard_coef: 0.7884 - val_loss: -0.7845 - val_jaccard_coef: 0.7845\n",
      "\n",
      "Epoch 00073: loss did not improve from -0.78960\n",
      "Epoch 74/200\n",
      "600/600 [==============================] - 567s 944ms/step - loss: -0.7861 - jaccard_coef: 0.7861 - val_loss: -0.7774 - val_jaccard_coef: 0.7774\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Epoch 00074: loss did not improve from -0.78960\n",
      "Epoch 75/200\n",
      "600/600 [==============================] - 560s 933ms/step - loss: -0.7876 - jaccard_coef: 0.7876 - val_loss: -0.7941 - val_jaccard_coef: 0.7941\n",
      "\n",
      "Epoch 00075: loss did not improve from -0.78960\n",
      "Epoch 76/200\n",
      "600/600 [==============================] - 564s 940ms/step - loss: -0.7877 - jaccard_coef: 0.7877 - val_loss: -0.7889 - val_jaccard_coef: 0.7889\n",
      "\n",
      "Epoch 00076: loss did not improve from -0.78960\n",
      "Epoch 77/200\n",
      "600/600 [==============================] - 568s 947ms/step - loss: -0.7775 - jaccard_coef: 0.7775 - val_loss: -0.7764 - val_jaccard_coef: 0.7764\n",
      "\n",
      "Epoch 00077: loss did not improve from -0.78960\n",
      "Epoch 78/200\n",
      "600/600 [==============================] - 569s 948ms/step - loss: -0.7893 - jaccard_coef: 0.7893 - val_loss: -0.7889 - val_jaccard_coef: 0.7889\n",
      "\n",
      "Epoch 00078: loss did not improve from -0.78960\n",
      "Epoch 79/200\n",
      "600/600 [==============================] - 560s 934ms/step - loss: -0.7871 - jaccard_coef: 0.7871 - val_loss: -0.7746 - val_jaccard_coef: 0.7746\n",
      "\n",
      "Epoch 00079: loss did not improve from -0.78960\n",
      "Epoch 80/200\n",
      "600/600 [==============================] - 578s 964ms/step - loss: -0.7915 - jaccard_coef: 0.7915 - val_loss: -0.7806 - val_jaccard_coef: 0.7806\n",
      "\n",
      "Epoch 00080: loss improved from -0.78960 to -0.79135, saving model to unet_lesion.hdf5\n",
      "Epoch 81/200\n",
      "600/600 [==============================] - 550s 917ms/step - loss: -0.7888 - jaccard_coef: 0.7888 - val_loss: -0.7935 - val_jaccard_coef: 0.7935\n",
      "\n",
      "Epoch 00081: loss did not improve from -0.79135\n",
      "Epoch 82/200\n",
      "600/600 [==============================] - 575s 958ms/step - loss: -0.7857 - jaccard_coef: 0.7857 - val_loss: -0.7877 - val_jaccard_coef: 0.7877\n",
      "\n",
      "Epoch 00082: loss did not improve from -0.79135\n",
      "Epoch 83/200\n",
      "600/600 [==============================] - 564s 940ms/step - loss: -0.7974 - jaccard_coef: 0.7974 - val_loss: -0.7808 - val_jaccard_coef: 0.7808\n",
      "\n",
      "Epoch 00083: loss improved from -0.79135 to -0.79724, saving model to unet_lesion.hdf5\n",
      "Epoch 84/200\n",
      "600/600 [==============================] - 565s 941ms/step - loss: -0.7890 - jaccard_coef: 0.7890 - val_loss: -0.7541 - val_jaccard_coef: 0.7541\n",
      "\n",
      "Epoch 00084: loss did not improve from -0.79724\n",
      "Epoch 85/200\n",
      "600/600 [==============================] - 571s 952ms/step - loss: -0.7842 - jaccard_coef: 0.7842 - val_loss: -0.7814 - val_jaccard_coef: 0.7814\n",
      "\n",
      "Epoch 00085: loss did not improve from -0.79724\n",
      "Epoch 86/200\n",
      "600/600 [==============================] - 561s 936ms/step - loss: -0.7919 - jaccard_coef: 0.7919 - val_loss: -0.7768 - val_jaccard_coef: 0.7768\n",
      "\n",
      "Epoch 00086: loss did not improve from -0.79724\n",
      "Epoch 87/200\n",
      "600/600 [==============================] - 558s 931ms/step - loss: -0.7926 - jaccard_coef: 0.7926 - val_loss: -0.7887 - val_jaccard_coef: 0.7887\n",
      "\n",
      "Epoch 00087: loss did not improve from -0.79724\n",
      "Epoch 88/200\n",
      "600/600 [==============================] - 567s 945ms/step - loss: -0.7904 - jaccard_coef: 0.7904 - val_loss: -0.7802 - val_jaccard_coef: 0.7802\n",
      "\n",
      "Epoch 00088: loss did not improve from -0.79724\n",
      "Epoch 89/200\n",
      "600/600 [==============================] - 568s 946ms/step - loss: -0.7851 - jaccard_coef: 0.7851 - val_loss: -0.7737 - val_jaccard_coef: 0.7737\n",
      "\n",
      "Epoch 00089: loss did not improve from -0.79724\n",
      "Epoch 90/200\n",
      "600/600 [==============================] - 565s 942ms/step - loss: -0.7924 - jaccard_coef: 0.7924 - val_loss: -0.7914 - val_jaccard_coef: 0.7914\n",
      "\n",
      "Epoch 00090: loss did not improve from -0.79724\n",
      "Epoch 91/200\n",
      "600/600 [==============================] - 566s 943ms/step - loss: -0.7958 - jaccard_coef: 0.7958 - val_loss: -0.7953 - val_jaccard_coef: 0.7953\n",
      "\n",
      "Epoch 00091: loss did not improve from -0.79724\n",
      "Epoch 92/200\n",
      "600/600 [==============================] - 564s 941ms/step - loss: -0.7927 - jaccard_coef: 0.7927 - val_loss: -0.7786 - val_jaccard_coef: 0.7786\n",
      "\n",
      "Epoch 00092: loss did not improve from -0.79724\n",
      "Epoch 93/200\n",
      "600/600 [==============================] - 572s 954ms/step - loss: -0.7845 - jaccard_coef: 0.7845 - val_loss: -0.7768 - val_jaccard_coef: 0.7768\n",
      "\n",
      "Epoch 00093: loss did not improve from -0.79724\n",
      "Epoch 94/200\n",
      "600/600 [==============================] - 567s 945ms/step - loss: -0.7877 - jaccard_coef: 0.7877 - val_loss: -0.7789 - val_jaccard_coef: 0.7789\n",
      "\n",
      "Epoch 00094: loss did not improve from -0.79724\n",
      "Epoch 95/200\n",
      "600/600 [==============================] - 560s 933ms/step - loss: -0.7943 - jaccard_coef: 0.7943 - val_loss: -0.7714 - val_jaccard_coef: 0.7714\n",
      "\n",
      "Epoch 00095: loss did not improve from -0.79724\n",
      "Epoch 96/200\n",
      "600/600 [==============================] - 567s 945ms/step - loss: -0.7919 - jaccard_coef: 0.7919 - val_loss: -0.7836 - val_jaccard_coef: 0.7836\n",
      "\n",
      "Epoch 00096: loss did not improve from -0.79724\n",
      "Epoch 97/200\n",
      "600/600 [==============================] - 564s 939ms/step - loss: -0.7963 - jaccard_coef: 0.7963 - val_loss: -0.7864 - val_jaccard_coef: 0.7864\n",
      "\n",
      "Epoch 00097: loss did not improve from -0.79724\n",
      "Epoch 98/200\n",
      "600/600 [==============================] - 568s 946ms/step - loss: -0.7914 - jaccard_coef: 0.7914 - val_loss: -0.7815 - val_jaccard_coef: 0.7815\n",
      "\n",
      "Epoch 00098: loss did not improve from -0.79724\n",
      "Epoch 99/200\n",
      "600/600 [==============================] - 568s 947ms/step - loss: -0.7934 - jaccard_coef: 0.7934 - val_loss: -0.7914 - val_jaccard_coef: 0.7914\n",
      "\n",
      "Epoch 00099: loss did not improve from -0.79724\n",
      "Epoch 100/200\n",
      "600/600 [==============================] - 563s 938ms/step - loss: -0.7886 - jaccard_coef: 0.7886 - val_loss: -0.7811 - val_jaccard_coef: 0.7811\n",
      "\n",
      "Epoch 00100: loss did not improve from -0.79724\n",
      "Epoch 101/200\n",
      "600/600 [==============================] - 574s 957ms/step - loss: -0.8024 - jaccard_coef: 0.8024 - val_loss: -0.7780 - val_jaccard_coef: 0.7780\n",
      "\n",
      "Epoch 00101: loss improved from -0.79724 to -0.80227, saving model to unet_lesion.hdf5\n",
      "Epoch 102/200\n",
      "600/600 [==============================] - 561s 935ms/step - loss: -0.7998 - jaccard_coef: 0.7998 - val_loss: -0.7947 - val_jaccard_coef: 0.7947\n",
      "\n",
      "Epoch 00102: loss did not improve from -0.80227\n",
      "Epoch 103/200\n",
      "600/600 [==============================] - 570s 949ms/step - loss: -0.7946 - jaccard_coef: 0.7946 - val_loss: -0.7894 - val_jaccard_coef: 0.7894\n",
      "\n",
      "Epoch 00103: loss did not improve from -0.80227\n",
      "Epoch 104/200\n",
      "600/600 [==============================] - 566s 943ms/step - loss: -0.7941 - jaccard_coef: 0.7941 - val_loss: -0.7793 - val_jaccard_coef: 0.7793\n",
      "\n",
      "Epoch 00104: loss did not improve from -0.80227\n",
      "Epoch 105/200\n",
      "600/600 [==============================] - 560s 934ms/step - loss: -0.7989 - jaccard_coef: 0.7989 - val_loss: -0.7990 - val_jaccard_coef: 0.7990\n",
      "\n",
      "Epoch 00105: loss did not improve from -0.80227\n",
      "Epoch 106/200\n",
      "600/600 [==============================] - 571s 952ms/step - loss: -0.7924 - jaccard_coef: 0.7924 - val_loss: -0.7977 - val_jaccard_coef: 0.7977\n",
      "\n",
      "Epoch 00106: loss did not improve from -0.80227\n",
      "Epoch 107/200\n",
      "600/600 [==============================] - 573s 955ms/step - loss: -0.7983 - jaccard_coef: 0.7983 - val_loss: -0.7790 - val_jaccard_coef: 0.7790\n",
      "\n",
      "Epoch 00107: loss did not improve from -0.80227\n",
      "Epoch 108/200\n",
      "600/600 [==============================] - 561s 936ms/step - loss: -0.7988 - jaccard_coef: 0.7988 - val_loss: -0.7871 - val_jaccard_coef: 0.7871\n",
      "\n",
      "Epoch 00108: loss did not improve from -0.80227\n",
      "Epoch 109/200\n",
      "600/600 [==============================] - 564s 940ms/step - loss: -0.7957 - jaccard_coef: 0.7957 - val_loss: -0.7862 - val_jaccard_coef: 0.7862\n",
      "\n",
      "Epoch 00109: loss did not improve from -0.80227\n",
      "Epoch 110/200\n",
      "600/600 [==============================] - 564s 939ms/step - loss: -0.7915 - jaccard_coef: 0.7915 - val_loss: -0.7758 - val_jaccard_coef: 0.7758\n",
      "\n",
      "Epoch 00110: loss did not improve from -0.80227\n",
      "Epoch 111/200\n",
      "600/600 [==============================] - 558s 931ms/step - loss: -0.8006 - jaccard_coef: 0.8006 - val_loss: -0.7894 - val_jaccard_coef: 0.7894\n",
      "\n",
      "Epoch 00111: loss did not improve from -0.80227\n",
      "Epoch 112/200\n",
      "600/600 [==============================] - 577s 962ms/step - loss: -0.8006 - jaccard_coef: 0.8006 - val_loss: -0.7742 - val_jaccard_coef: 0.7742\n",
      "\n",
      "Epoch 00112: loss did not improve from -0.80227\n",
      "Epoch 113/200\n",
      "600/600 [==============================] - 554s 923ms/step - loss: -0.8007 - jaccard_coef: 0.8007 - val_loss: -0.7943 - val_jaccard_coef: 0.7943\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Epoch 00113: loss did not improve from -0.80227\n",
      "Epoch 114/200\n",
      "600/600 [==============================] - 579s 965ms/step - loss: -0.8030 - jaccard_coef: 0.8030 - val_loss: -0.7896 - val_jaccard_coef: 0.7896\n",
      "\n",
      "Epoch 00114: loss improved from -0.80227 to -0.80298, saving model to unet_lesion.hdf5\n",
      "Epoch 115/200\n",
      "600/600 [==============================] - 569s 949ms/step - loss: -0.8001 - jaccard_coef: 0.8001 - val_loss: -0.7580 - val_jaccard_coef: 0.7580\n",
      "\n",
      "Epoch 00115: loss did not improve from -0.80298\n",
      "Epoch 116/200\n",
      "600/600 [==============================] - 558s 930ms/step - loss: -0.8015 - jaccard_coef: 0.8015 - val_loss: -0.7859 - val_jaccard_coef: 0.7859\n",
      "\n",
      "Epoch 00116: loss did not improve from -0.80298\n",
      "Epoch 117/200\n",
      "600/600 [==============================] - 582s 969ms/step - loss: -0.7996 - jaccard_coef: 0.7996 - val_loss: -0.7866 - val_jaccard_coef: 0.7866\n",
      "\n",
      "Epoch 00117: loss did not improve from -0.80298\n",
      "Epoch 118/200\n",
      "600/600 [==============================] - 559s 931ms/step - loss: -0.7993 - jaccard_coef: 0.7993 - val_loss: -0.7979 - val_jaccard_coef: 0.7979\n",
      "\n",
      "Epoch 00118: loss did not improve from -0.80298\n",
      "Epoch 119/200\n",
      "600/600 [==============================] - 571s 952ms/step - loss: -0.8053 - jaccard_coef: 0.8053 - val_loss: -0.7916 - val_jaccard_coef: 0.7916\n",
      "\n",
      "Epoch 00119: loss improved from -0.80298 to -0.80523, saving model to unet_lesion.hdf5\n",
      "Epoch 120/200\n",
      "600/600 [==============================] - 558s 930ms/step - loss: -0.7971 - jaccard_coef: 0.7971 - val_loss: -0.7867 - val_jaccard_coef: 0.7867\n",
      "\n",
      "Epoch 00120: loss did not improve from -0.80523\n",
      "Epoch 121/200\n",
      "600/600 [==============================] - 569s 948ms/step - loss: -0.8060 - jaccard_coef: 0.8060 - val_loss: -0.7998 - val_jaccard_coef: 0.7998\n",
      "\n",
      "Epoch 00121: loss improved from -0.80523 to -0.80606, saving model to unet_lesion.hdf5\n",
      "Epoch 122/200\n",
      "600/600 [==============================] - 566s 943ms/step - loss: -0.8025 - jaccard_coef: 0.8025 - val_loss: -0.7969 - val_jaccard_coef: 0.7969\n",
      "\n",
      "Epoch 00122: loss did not improve from -0.80606\n",
      "Epoch 123/200\n",
      "600/600 [==============================] - 599s 998ms/step - loss: -0.8016 - jaccard_coef: 0.8016 - val_loss: -0.7983 - val_jaccard_coef: 0.7983\n",
      "\n",
      "Epoch 00123: loss did not improve from -0.80606\n",
      "Epoch 124/200\n",
      "600/600 [==============================] - 604s 1s/step - loss: -0.8038 - jaccard_coef: 0.8038 - val_loss: -0.7788 - val_jaccard_coef: 0.7788\n",
      "\n",
      "Epoch 00124: loss did not improve from -0.80606\n",
      "Epoch 125/200\n",
      "600/600 [==============================] - 598s 996ms/step - loss: -0.8048 - jaccard_coef: 0.8048 - val_loss: -0.7960 - val_jaccard_coef: 0.7960\n",
      "\n",
      "Epoch 00125: loss did not improve from -0.80606\n",
      "Epoch 126/200\n",
      "600/600 [==============================] - 607s 1s/step - loss: -0.8056 - jaccard_coef: 0.8056 - val_loss: -0.8050 - val_jaccard_coef: 0.8050\n",
      "\n",
      "Epoch 00126: loss did not improve from -0.80606\n",
      "Epoch 127/200\n",
      "600/600 [==============================] - 610s 1s/step - loss: -0.8091 - jaccard_coef: 0.8091 - val_loss: -0.7780 - val_jaccard_coef: 0.7780\n",
      "\n",
      "Epoch 00127: loss improved from -0.80606 to -0.80910, saving model to unet_lesion.hdf5\n",
      "Epoch 128/200\n",
      "600/600 [==============================] - 599s 999ms/step - loss: -0.8058 - jaccard_coef: 0.8058 - val_loss: -0.7841 - val_jaccard_coef: 0.7841\n",
      "\n",
      "Epoch 00128: loss did not improve from -0.80910\n",
      "Epoch 129/200\n",
      "600/600 [==============================] - 590s 983ms/step - loss: -0.8030 - jaccard_coef: 0.8030 - val_loss: -0.7876 - val_jaccard_coef: 0.7876\n",
      "\n",
      "Epoch 00129: loss did not improve from -0.80910\n",
      "Epoch 130/200\n",
      "600/600 [==============================] - 606s 1s/step - loss: -0.8044 - jaccard_coef: 0.8044 - val_loss: -0.7798 - val_jaccard_coef: 0.7798\n",
      "\n",
      "Epoch 00130: loss did not improve from -0.80910\n",
      "Epoch 131/200\n",
      "600/600 [==============================] - 619s 1s/step - loss: -0.8001 - jaccard_coef: 0.8001 - val_loss: -0.7865 - val_jaccard_coef: 0.7865\n",
      "\n",
      "Epoch 00131: loss did not improve from -0.80910\n",
      "Epoch 132/200\n",
      "600/600 [==============================] - 587s 979ms/step - loss: -0.8054 - jaccard_coef: 0.8054 - val_loss: -0.8002 - val_jaccard_coef: 0.8002\n",
      "\n",
      "Epoch 00132: loss did not improve from -0.80910\n",
      "Epoch 133/200\n",
      "600/600 [==============================] - 615s 1s/step - loss: -0.8132 - jaccard_coef: 0.8132 - val_loss: -0.7926 - val_jaccard_coef: 0.7926\n",
      "\n",
      "Epoch 00133: loss improved from -0.80910 to -0.81356, saving model to unet_lesion.hdf5\n",
      "Epoch 134/200\n",
      "600/600 [==============================] - 606s 1s/step - loss: -0.8055 - jaccard_coef: 0.8055 - val_loss: -0.7948 - val_jaccard_coef: 0.7948\n",
      "\n",
      "Epoch 00134: loss did not improve from -0.81356\n",
      "Epoch 135/200\n",
      "600/600 [==============================] - 597s 995ms/step - loss: -0.8060 - jaccard_coef: 0.8060 - val_loss: -0.7895 - val_jaccard_coef: 0.7895\n",
      "\n",
      "Epoch 00135: loss did not improve from -0.81356\n",
      "Epoch 136/200\n",
      "600/600 [==============================] - 610s 1s/step - loss: -0.8060 - jaccard_coef: 0.8060 - val_loss: -0.7977 - val_jaccard_coef: 0.7977\n",
      "\n",
      "Epoch 00136: loss did not improve from -0.81356\n",
      "Epoch 137/200\n",
      "600/600 [==============================] - 602s 1s/step - loss: -0.8100 - jaccard_coef: 0.8100 - val_loss: -0.7845 - val_jaccard_coef: 0.7845\n",
      "\n",
      "Epoch 00137: loss did not improve from -0.81356\n",
      "Epoch 138/200\n",
      "600/600 [==============================] - 607s 1s/step - loss: -0.8086 - jaccard_coef: 0.8086 - val_loss: -0.7989 - val_jaccard_coef: 0.7989\n",
      "\n",
      "Epoch 00138: loss did not improve from -0.81356\n",
      "Epoch 139/200\n",
      "600/600 [==============================] - 591s 985ms/step - loss: -0.8089 - jaccard_coef: 0.8089 - val_loss: -0.7965 - val_jaccard_coef: 0.7965\n",
      "\n",
      "Epoch 00139: loss did not improve from -0.81356\n",
      "Epoch 140/200\n",
      "600/600 [==============================] - 616s 1s/step - loss: -0.8094 - jaccard_coef: 0.8094 - val_loss: -0.7880 - val_jaccard_coef: 0.7880\n",
      "\n",
      "Epoch 00140: loss did not improve from -0.81356\n",
      "Epoch 141/200\n",
      "600/600 [==============================] - 597s 994ms/step - loss: -0.8098 - jaccard_coef: 0.8098 - val_loss: -0.7956 - val_jaccard_coef: 0.7956\n",
      "\n",
      "Epoch 00141: loss did not improve from -0.81356\n",
      "Epoch 142/200\n",
      "600/600 [==============================] - 595s 992ms/step - loss: -0.8165 - jaccard_coef: 0.8165 - val_loss: -0.7974 - val_jaccard_coef: 0.7974\n",
      "\n",
      "Epoch 00142: loss improved from -0.81356 to -0.81642, saving model to unet_lesion.hdf5\n",
      "Epoch 143/200\n",
      "600/600 [==============================] - 564s 939ms/step - loss: -0.8065 - jaccard_coef: 0.8065 - val_loss: -0.7895 - val_jaccard_coef: 0.7895\n",
      "\n",
      "Epoch 00143: loss did not improve from -0.81642\n",
      "Epoch 144/200\n",
      "600/600 [==============================] - 567s 945ms/step - loss: -0.8113 - jaccard_coef: 0.8113 - val_loss: -0.7996 - val_jaccard_coef: 0.7996\n",
      "\n",
      "Epoch 00144: loss did not improve from -0.81642\n",
      "Epoch 145/200\n",
      "600/600 [==============================] - 561s 935ms/step - loss: -0.8117 - jaccard_coef: 0.8117 - val_loss: -0.7929 - val_jaccard_coef: 0.7929\n",
      "\n",
      "Epoch 00145: loss did not improve from -0.81642\n",
      "Epoch 146/200\n",
      "600/600 [==============================] - 574s 956ms/step - loss: -0.8129 - jaccard_coef: 0.8129 - val_loss: -0.7916 - val_jaccard_coef: 0.7916\n",
      "\n",
      "Epoch 00146: loss did not improve from -0.81642\n",
      "Epoch 147/200\n",
      "600/600 [==============================] - 557s 929ms/step - loss: -0.8062 - jaccard_coef: 0.8062 - val_loss: -0.8016 - val_jaccard_coef: 0.8016\n",
      "\n",
      "Epoch 00147: loss did not improve from -0.81642\n",
      "Epoch 148/200\n",
      "600/600 [==============================] - 599s 999ms/step - loss: -0.8067 - jaccard_coef: 0.8067 - val_loss: -0.7859 - val_jaccard_coef: 0.7859\n",
      "\n",
      "Epoch 00148: loss did not improve from -0.81642\n",
      "Epoch 149/200\n",
      "600/600 [==============================] - 611s 1s/step - loss: -0.8090 - jaccard_coef: 0.8090 - val_loss: -0.8008 - val_jaccard_coef: 0.8008\n",
      "\n",
      "Epoch 00149: loss did not improve from -0.81642\n",
      "Epoch 150/200\n",
      "600/600 [==============================] - 604s 1s/step - loss: -0.8165 - jaccard_coef: 0.8165 - val_loss: -0.8073 - val_jaccard_coef: 0.8073\n",
      "\n",
      "Epoch 00150: loss improved from -0.81642 to -0.81695, saving model to unet_lesion.hdf5\n",
      "Epoch 151/200\n",
      "600/600 [==============================] - 598s 997ms/step - loss: -0.8103 - jaccard_coef: 0.8103 - val_loss: -0.7836 - val_jaccard_coef: 0.7836\n",
      "\n",
      "Epoch 00151: loss did not improve from -0.81695\n",
      "Epoch 152/200\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "600/600 [==============================] - 604s 1s/step - loss: -0.8104 - jaccard_coef: 0.8104 - val_loss: -0.7933 - val_jaccard_coef: 0.7933\n",
      "\n",
      "Epoch 00152: loss did not improve from -0.81695\n",
      "Epoch 153/200\n",
      "600/600 [==============================] - 603s 1s/step - loss: -0.8133 - jaccard_coef: 0.8133 - val_loss: -0.7891 - val_jaccard_coef: 0.7891\n",
      "\n",
      "Epoch 00153: loss did not improve from -0.81695\n",
      "Epoch 154/200\n",
      "600/600 [==============================] - 615s 1s/step - loss: -0.8179 - jaccard_coef: 0.8179 - val_loss: -0.7908 - val_jaccard_coef: 0.7908\n",
      "\n",
      "Epoch 00154: loss improved from -0.81695 to -0.81779, saving model to unet_lesion.hdf5\n",
      "Epoch 155/200\n",
      "600/600 [==============================] - 604s 1s/step - loss: -0.8094 - jaccard_coef: 0.8094 - val_loss: -0.7885 - val_jaccard_coef: 0.7885\n",
      "\n",
      "Epoch 00155: loss did not improve from -0.81779\n",
      "Epoch 156/200\n",
      "600/600 [==============================] - 597s 994ms/step - loss: -0.8060 - jaccard_coef: 0.8060 - val_loss: -0.8042 - val_jaccard_coef: 0.8042\n",
      "\n",
      "Epoch 00156: loss did not improve from -0.81779\n",
      "Epoch 157/200\n",
      "600/600 [==============================] - 611s 1s/step - loss: -0.8143 - jaccard_coef: 0.8143 - val_loss: -0.7932 - val_jaccard_coef: 0.7932\n",
      "\n",
      "Epoch 00157: loss did not improve from -0.81779\n",
      "Epoch 158/200\n",
      "600/600 [==============================] - 598s 997ms/step - loss: -0.8094 - jaccard_coef: 0.8094 - val_loss: -0.7900 - val_jaccard_coef: 0.7900\n",
      "\n",
      "Epoch 00158: loss did not improve from -0.81779\n",
      "Epoch 159/200\n",
      "600/600 [==============================] - 601s 1s/step - loss: -0.8097 - jaccard_coef: 0.8097 - val_loss: -0.7952 - val_jaccard_coef: 0.7952\n",
      "\n",
      "Epoch 00159: loss did not improve from -0.81779\n",
      "Epoch 160/200\n",
      "600/600 [==============================] - 608s 1s/step - loss: -0.8141 - jaccard_coef: 0.8141 - val_loss: -0.7737 - val_jaccard_coef: 0.7737\n",
      "\n",
      "Epoch 00160: loss did not improve from -0.81779\n",
      "Epoch 161/200\n",
      "600/600 [==============================] - 607s 1s/step - loss: -0.8122 - jaccard_coef: 0.8122 - val_loss: -0.8025 - val_jaccard_coef: 0.8025\n",
      "\n",
      "Epoch 00161: loss did not improve from -0.81779\n",
      "Epoch 162/200\n",
      "600/600 [==============================] - 600s 1000ms/step - loss: -0.8143 - jaccard_coef: 0.8143 - val_loss: -0.7800 - val_jaccard_coef: 0.7800\n",
      "\n",
      "Epoch 00162: loss did not improve from -0.81779\n",
      "Epoch 163/200\n",
      "600/600 [==============================] - 611s 1s/step - loss: -0.8200 - jaccard_coef: 0.8200 - val_loss: -0.8048 - val_jaccard_coef: 0.8048\n",
      "\n",
      "Epoch 00163: loss improved from -0.81779 to -0.82011, saving model to unet_lesion.hdf5\n",
      "Epoch 164/200\n",
      "600/600 [==============================] - 596s 994ms/step - loss: -0.8113 - jaccard_coef: 0.8113 - val_loss: -0.7920 - val_jaccard_coef: 0.7920\n",
      "\n",
      "Epoch 00164: loss did not improve from -0.82011\n",
      "Epoch 165/200\n",
      "600/600 [==============================] - 594s 991ms/step - loss: -0.8227 - jaccard_coef: 0.8227 - val_loss: -0.8042 - val_jaccard_coef: 0.8042\n",
      "\n",
      "Epoch 00165: loss improved from -0.82011 to -0.82262, saving model to unet_lesion.hdf5\n",
      "Epoch 166/200\n",
      "600/600 [==============================] - 607s 1s/step - loss: -0.8159 - jaccard_coef: 0.8159 - val_loss: -0.7880 - val_jaccard_coef: 0.7880\n",
      "\n",
      "Epoch 00166: loss did not improve from -0.82262\n",
      "Epoch 167/200\n",
      "600/600 [==============================] - 604s 1s/step - loss: -0.8127 - jaccard_coef: 0.8127 - val_loss: -0.7918 - val_jaccard_coef: 0.7918\n",
      "\n",
      "Epoch 00167: loss did not improve from -0.82262\n",
      "Epoch 168/200\n",
      "600/600 [==============================] - 601s 1s/step - loss: -0.8159 - jaccard_coef: 0.8159 - val_loss: -0.7850 - val_jaccard_coef: 0.7850\n",
      "\n",
      "Epoch 00168: loss did not improve from -0.82262\n",
      "Epoch 169/200\n",
      "600/600 [==============================] - 604s 1s/step - loss: -0.8212 - jaccard_coef: 0.8212 - val_loss: -0.8072 - val_jaccard_coef: 0.8072\n",
      "\n",
      "Epoch 00169: loss did not improve from -0.82262\n",
      "Epoch 170/200\n",
      "600/600 [==============================] - 586s 976ms/step - loss: -0.8135 - jaccard_coef: 0.8135 - val_loss: -0.7959 - val_jaccard_coef: 0.7959\n",
      "\n",
      "Epoch 00170: loss did not improve from -0.82262\n",
      "Epoch 171/200\n",
      "600/600 [==============================] - 555s 924ms/step - loss: -0.8183 - jaccard_coef: 0.8183 - val_loss: -0.7992 - val_jaccard_coef: 0.7992\n",
      "\n",
      "Epoch 00171: loss did not improve from -0.82262\n",
      "Epoch 172/200\n",
      "600/600 [==============================] - 574s 957ms/step - loss: -0.8155 - jaccard_coef: 0.8155 - val_loss: -0.7849 - val_jaccard_coef: 0.7849\n",
      "\n",
      "Epoch 00172: loss did not improve from -0.82262\n",
      "Epoch 173/200\n",
      "600/600 [==============================] - 565s 942ms/step - loss: -0.8149 - jaccard_coef: 0.8149 - val_loss: -0.7925 - val_jaccard_coef: 0.7925\n",
      "\n",
      "Epoch 00173: loss did not improve from -0.82262\n",
      "Epoch 174/200\n",
      "600/600 [==============================] - 563s 939ms/step - loss: -0.8160 - jaccard_coef: 0.8160 - val_loss: -0.7953 - val_jaccard_coef: 0.7953\n",
      "\n",
      "Epoch 00174: loss did not improve from -0.82262\n",
      "Epoch 175/200\n",
      "600/600 [==============================] - 560s 933ms/step - loss: -0.8144 - jaccard_coef: 0.8144 - val_loss: -0.7957 - val_jaccard_coef: 0.7957\n",
      "\n",
      "Epoch 00175: loss did not improve from -0.82262\n",
      "Epoch 176/200\n",
      "600/600 [==============================] - 579s 966ms/step - loss: -0.8195 - jaccard_coef: 0.8195 - val_loss: -0.7916 - val_jaccard_coef: 0.7916\n",
      "\n",
      "Epoch 00176: loss did not improve from -0.82262\n",
      "Epoch 177/200\n",
      "600/600 [==============================] - 553s 922ms/step - loss: -0.8218 - jaccard_coef: 0.8218 - val_loss: -0.7969 - val_jaccard_coef: 0.7969\n",
      "\n",
      "Epoch 00177: loss did not improve from -0.82262\n",
      "Epoch 178/200\n",
      "600/600 [==============================] - 579s 966ms/step - loss: -0.8104 - jaccard_coef: 0.8104 - val_loss: -0.7951 - val_jaccard_coef: 0.7951\n",
      "\n",
      "Epoch 00178: loss did not improve from -0.82262\n",
      "Epoch 179/200\n",
      "600/600 [==============================] - 571s 952ms/step - loss: -0.8176 - jaccard_coef: 0.8176 - val_loss: -0.7831 - val_jaccard_coef: 0.7831\n",
      "\n",
      "Epoch 00179: loss did not improve from -0.82262\n",
      "Epoch 180/200\n",
      "600/600 [==============================] - 574s 956ms/step - loss: -0.8186 - jaccard_coef: 0.8186 - val_loss: -0.7952 - val_jaccard_coef: 0.7952\n",
      "\n",
      "Epoch 00180: loss did not improve from -0.82262\n",
      "Epoch 181/200\n",
      "600/600 [==============================] - 567s 945ms/step - loss: -0.8167 - jaccard_coef: 0.8167 - val_loss: -0.7860 - val_jaccard_coef: 0.7860\n",
      "\n",
      "Epoch 00181: loss did not improve from -0.82262\n",
      "Epoch 182/200\n",
      "600/600 [==============================] - 563s 939ms/step - loss: -0.8212 - jaccard_coef: 0.8212 - val_loss: -0.8015 - val_jaccard_coef: 0.8015\n",
      "\n",
      "Epoch 00182: loss did not improve from -0.82262\n",
      "Epoch 183/200\n",
      "600/600 [==============================] - 576s 959ms/step - loss: -0.8153 - jaccard_coef: 0.8153 - val_loss: -0.7954 - val_jaccard_coef: 0.7954\n",
      "\n",
      "Epoch 00183: loss did not improve from -0.82262\n",
      "Epoch 184/200\n",
      "600/600 [==============================] - 557s 928ms/step - loss: -0.8221 - jaccard_coef: 0.8221 - val_loss: -0.7865 - val_jaccard_coef: 0.7865\n",
      "\n",
      "Epoch 00184: loss did not improve from -0.82262\n",
      "Epoch 185/200\n",
      "600/600 [==============================] - 569s 948ms/step - loss: -0.8182 - jaccard_coef: 0.8182 - val_loss: -0.7891 - val_jaccard_coef: 0.7891\n",
      "\n",
      "Epoch 00185: loss did not improve from -0.82262\n",
      "Epoch 186/200\n",
      "600/600 [==============================] - 563s 938ms/step - loss: -0.8138 - jaccard_coef: 0.8138 - val_loss: -0.8010 - val_jaccard_coef: 0.8010\n",
      "\n",
      "Epoch 00186: loss did not improve from -0.82262\n",
      "Epoch 187/200\n",
      "600/600 [==============================] - 558s 931ms/step - loss: -0.8180 - jaccard_coef: 0.8180 - val_loss: -0.7937 - val_jaccard_coef: 0.7937\n",
      "\n",
      "Epoch 00187: loss did not improve from -0.82262\n",
      "Epoch 188/200\n",
      "600/600 [==============================] - 560s 934ms/step - loss: -0.8226 - jaccard_coef: 0.8226 - val_loss: -0.8018 - val_jaccard_coef: 0.8018\n",
      "\n",
      "Epoch 00188: loss improved from -0.82262 to -0.82279, saving model to unet_lesion.hdf5\n",
      "Epoch 189/200\n",
      "600/600 [==============================] - 583s 971ms/step - loss: -0.8201 - jaccard_coef: 0.8201 - val_loss: -0.8113 - val_jaccard_coef: 0.8113\n",
      "\n",
      "Epoch 00189: loss did not improve from -0.82279\n",
      "Epoch 190/200\n",
      "600/600 [==============================] - 559s 931ms/step - loss: -0.8234 - jaccard_coef: 0.8234 - val_loss: -0.8013 - val_jaccard_coef: 0.8013\n",
      "\n",
      "Epoch 00190: loss improved from -0.82279 to -0.82332, saving model to unet_lesion.hdf5\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 191/200\n",
      "600/600 [==============================] - 560s 934ms/step - loss: -0.8250 - jaccard_coef: 0.8250 - val_loss: -0.7924 - val_jaccard_coef: 0.7924\n",
      "\n",
      "Epoch 00191: loss improved from -0.82332 to -0.82534, saving model to unet_lesion.hdf5\n",
      "Epoch 192/200\n",
      "600/600 [==============================] - 572s 953ms/step - loss: -0.8200 - jaccard_coef: 0.8200 - val_loss: -0.7960 - val_jaccard_coef: 0.7960\n",
      "\n",
      "Epoch 00192: loss did not improve from -0.82534\n",
      "Epoch 193/200\n",
      "600/600 [==============================] - 558s 929ms/step - loss: -0.8190 - jaccard_coef: 0.8190 - val_loss: -0.8089 - val_jaccard_coef: 0.8089\n",
      "\n",
      "Epoch 00193: loss did not improve from -0.82534\n",
      "Epoch 194/200\n",
      "600/600 [==============================] - 582s 970ms/step - loss: -0.8221 - jaccard_coef: 0.8221 - val_loss: -0.7824 - val_jaccard_coef: 0.7824\n",
      "\n",
      "Epoch 00194: loss did not improve from -0.82534\n",
      "Epoch 195/200\n",
      "600/600 [==============================] - 571s 952ms/step - loss: -0.8264 - jaccard_coef: 0.8264 - val_loss: -0.7973 - val_jaccard_coef: 0.7973\n",
      "\n",
      "Epoch 00195: loss improved from -0.82534 to -0.82631, saving model to unet_lesion.hdf5\n",
      "Epoch 196/200\n",
      "600/600 [==============================] - 571s 952ms/step - loss: -0.8285 - jaccard_coef: 0.8285 - val_loss: -0.8074 - val_jaccard_coef: 0.8074\n",
      "\n",
      "Epoch 00196: loss improved from -0.82631 to -0.82864, saving model to unet_lesion.hdf5\n",
      "Epoch 197/200\n",
      "600/600 [==============================] - 571s 952ms/step - loss: -0.8274 - jaccard_coef: 0.8274 - val_loss: -0.7874 - val_jaccard_coef: 0.7874\n",
      "\n",
      "Epoch 00197: loss did not improve from -0.82864\n",
      "Epoch 198/200\n",
      "600/600 [==============================] - 565s 942ms/step - loss: -0.8210 - jaccard_coef: 0.8210 - val_loss: -0.7917 - val_jaccard_coef: 0.7917\n",
      "\n",
      "Epoch 00198: loss did not improve from -0.82864\n",
      "Epoch 199/200\n",
      "600/600 [==============================] - 573s 955ms/step - loss: -0.8291 - jaccard_coef: 0.8291 - val_loss: -0.8081 - val_jaccard_coef: 0.8081\n",
      "\n",
      "Epoch 00199: loss improved from -0.82864 to -0.82894, saving model to unet_lesion.hdf5\n",
      "Epoch 200/200\n",
      "600/600 [==============================] - 561s 935ms/step - loss: -0.8271 - jaccard_coef: 0.8271 - val_loss: -0.7982 - val_jaccard_coef: 0.7982\n",
      "\n",
      "Epoch 00200: loss did not improve from -0.82894\n"
     ]
    }
   ],
   "source": [
    "\n",
    "#Train\n",
    "history = model.fit_generator(\n",
    "    myGene,\n",
    "    steps_per_epoch = 600, \n",
    "    epochs=200,\n",
    "    callbacks=[model_checkpoint,tensorBoard],\n",
    "    validation_data=myValGene,\n",
    "    validation_steps=200)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 126/200\n",
      "1000/1000 [==============================] - 911s 911ms/step - loss: -0.7609 - jaccard_coef: 0.7609 - val_loss: -0.7301 - val_jaccard_coef: 0.7301\n",
      "\n",
      "Epoch 00126: loss improved from inf to -0.76097, saving model to unet_lesion.hdf5\n",
      "Epoch 127/200\n",
      "1000/1000 [==============================] - 891s 891ms/step - loss: -0.7529 - jaccard_coef: 0.7529 - val_loss: -0.7368 - val_jaccard_coef: 0.7368\n",
      "\n",
      "Epoch 00127: loss did not improve from -0.76097\n",
      "Epoch 128/200\n",
      "1000/1000 [==============================] - 887s 887ms/step - loss: -0.7641 - jaccard_coef: 0.7641 - val_loss: -0.7383 - val_jaccard_coef: 0.7383\n",
      "\n",
      "Epoch 00128: loss improved from -0.76097 to -0.76421, saving model to unet_lesion.hdf5\n",
      "Epoch 129/200\n",
      "1000/1000 [==============================] - 897s 897ms/step - loss: -0.7578 - jaccard_coef: 0.7578 - val_loss: -0.7526 - val_jaccard_coef: 0.7526\n",
      "\n",
      "Epoch 00129: loss did not improve from -0.76421\n",
      "Epoch 130/200\n",
      "1000/1000 [==============================] - 878s 878ms/step - loss: -0.7715 - jaccard_coef: 0.7715 - val_loss: -0.7801 - val_jaccard_coef: 0.7801\n",
      "\n",
      "Epoch 00130: loss improved from -0.76421 to -0.77173, saving model to unet_lesion.hdf5\n",
      "Epoch 131/200\n",
      "1000/1000 [==============================] - 897s 897ms/step - loss: -0.7724 - jaccard_coef: 0.7724 - val_loss: -0.7701 - val_jaccard_coef: 0.7701\n",
      "\n",
      "Epoch 00131: loss improved from -0.77173 to -0.77236, saving model to unet_lesion.hdf5\n",
      "Epoch 132/200\n",
      "1000/1000 [==============================] - 893s 893ms/step - loss: -0.7723 - jaccard_coef: 0.7723 - val_loss: -0.7712 - val_jaccard_coef: 0.7712\n",
      "\n",
      "Epoch 00132: loss did not improve from -0.77236\n",
      "Epoch 133/200\n",
      "1000/1000 [==============================] - 888s 888ms/step - loss: -0.7673 - jaccard_coef: 0.7673 - val_loss: -0.7697 - val_jaccard_coef: 0.7697\n",
      "\n",
      "Epoch 00133: loss did not improve from -0.77236\n",
      "Epoch 134/200\n",
      "1000/1000 [==============================] - 883s 883ms/step - loss: -0.7816 - jaccard_coef: 0.7816 - val_loss: -0.7432 - val_jaccard_coef: 0.7432\n",
      "\n",
      "Epoch 00134: loss improved from -0.77236 to -0.78153, saving model to unet_lesion.hdf5\n",
      "Epoch 135/200\n",
      "1000/1000 [==============================] - 898s 898ms/step - loss: -0.7739 - jaccard_coef: 0.7739 - val_loss: -0.7179 - val_jaccard_coef: 0.7179\n",
      "\n",
      "Epoch 00135: loss did not improve from -0.78153\n",
      "Epoch 136/200\n",
      "1000/1000 [==============================] - 883s 883ms/step - loss: -0.7707 - jaccard_coef: 0.7707 - val_loss: -0.7679 - val_jaccard_coef: 0.7679\n",
      "\n",
      "Epoch 00136: loss did not improve from -0.78153\n",
      "Epoch 137/200\n",
      "1000/1000 [==============================] - 883s 883ms/step - loss: -0.7734 - jaccard_coef: 0.7734 - val_loss: -0.7697 - val_jaccard_coef: 0.7697\n",
      "\n",
      "Epoch 00137: loss did not improve from -0.78153\n",
      "Epoch 138/200\n",
      "1000/1000 [==============================] - 889s 889ms/step - loss: -0.7805 - jaccard_coef: 0.7805 - val_loss: -0.7736 - val_jaccard_coef: 0.7736\n",
      "\n",
      "Epoch 00138: loss did not improve from -0.78153\n",
      "Epoch 139/200\n",
      "1000/1000 [==============================] - 884s 884ms/step - loss: -0.7773 - jaccard_coef: 0.7773 - val_loss: -0.7714 - val_jaccard_coef: 0.7714\n",
      "\n",
      "Epoch 00139: loss did not improve from -0.78153\n",
      "Epoch 140/200\n",
      "1000/1000 [==============================] - 872s 872ms/step - loss: -0.7783 - jaccard_coef: 0.7783 - val_loss: -0.7730 - val_jaccard_coef: 0.7730\n",
      "\n",
      "Epoch 00140: loss did not improve from -0.78153\n",
      "Epoch 141/200\n",
      "1000/1000 [==============================] - 892s 892ms/step - loss: -0.7817 - jaccard_coef: 0.7817 - val_loss: -0.7590 - val_jaccard_coef: 0.7590\n",
      "\n",
      "Epoch 00141: loss improved from -0.78153 to -0.78160, saving model to unet_lesion.hdf5\n",
      "Epoch 142/200\n",
      "1000/1000 [==============================] - 886s 886ms/step - loss: -0.7846 - jaccard_coef: 0.7846 - val_loss: -0.7670 - val_jaccard_coef: 0.7670\n",
      "\n",
      "Epoch 00142: loss improved from -0.78160 to -0.78468, saving model to unet_lesion.hdf5\n",
      "Epoch 143/200\n",
      "1000/1000 [==============================] - 876s 876ms/step - loss: -0.7856 - jaccard_coef: 0.7856 - val_loss: -0.7478 - val_jaccard_coef: 0.7478\n",
      "\n",
      "Epoch 00143: loss improved from -0.78468 to -0.78548, saving model to unet_lesion.hdf5\n",
      "Epoch 144/200\n",
      "1000/1000 [==============================] - 886s 886ms/step - loss: -0.7852 - jaccard_coef: 0.7852 - val_loss: -0.7648 - val_jaccard_coef: 0.7648\n",
      "\n",
      "Epoch 00144: loss did not improve from -0.78548\n",
      "Epoch 145/200\n",
      "1000/1000 [==============================] - 886s 886ms/step - loss: -0.7887 - jaccard_coef: 0.7887 - val_loss: -0.7718 - val_jaccard_coef: 0.7718\n",
      "\n",
      "Epoch 00145: loss improved from -0.78548 to -0.78857, saving model to unet_lesion.hdf5\n",
      "Epoch 146/200\n",
      "1000/1000 [==============================] - 896s 896ms/step - loss: -0.7835 - jaccard_coef: 0.7835 - val_loss: -0.7640 - val_jaccard_coef: 0.7640\n",
      "\n",
      "Epoch 00146: loss did not improve from -0.78857\n",
      "Epoch 147/200\n",
      "1000/1000 [==============================] - 879s 879ms/step - loss: -0.7942 - jaccard_coef: 0.7942 - val_loss: -0.7864 - val_jaccard_coef: 0.7864\n",
      "\n",
      "Epoch 00147: loss improved from -0.78857 to -0.79430, saving model to unet_lesion.hdf5\n",
      "Epoch 148/200\n",
      "1000/1000 [==============================] - 876s 876ms/step - loss: -0.7909 - jaccard_coef: 0.7909 - val_loss: -0.7580 - val_jaccard_coef: 0.7580\n",
      "\n",
      "Epoch 00148: loss did not improve from -0.79430\n",
      "Epoch 149/200\n",
      "1000/1000 [==============================] - 885s 885ms/step - loss: -0.7889 - jaccard_coef: 0.7889 - val_loss: -0.7869 - val_jaccard_coef: 0.7869\n",
      "\n",
      "Epoch 00149: loss did not improve from -0.79430\n",
      "Epoch 150/200\n",
      "1000/1000 [==============================] - 891s 891ms/step - loss: -0.7973 - jaccard_coef: 0.7973 - val_loss: -0.7788 - val_jaccard_coef: 0.7788\n",
      "\n",
      "Epoch 00150: loss improved from -0.79430 to -0.79720, saving model to unet_lesion.hdf5\n",
      "Epoch 151/200\n",
      "1000/1000 [==============================] - 890s 890ms/step - loss: -0.7887 - jaccard_coef: 0.7887 - val_loss: -0.7789 - val_jaccard_coef: 0.7789\n",
      "\n",
      "Epoch 00151: loss did not improve from -0.79720\n",
      "Epoch 152/200\n",
      "1000/1000 [==============================] - 884s 884ms/step - loss: -0.7897 - jaccard_coef: 0.7897 - val_loss: -0.7705 - val_jaccard_coef: 0.7705\n",
      "\n",
      "Epoch 00152: loss did not improve from -0.79720\n",
      "Epoch 153/200\n",
      "1000/1000 [==============================] - 891s 891ms/step - loss: -0.7921 - jaccard_coef: 0.7921 - val_loss: -0.7540 - val_jaccard_coef: 0.7540\n",
      "\n",
      "Epoch 00153: loss did not improve from -0.79720\n",
      "Epoch 154/200\n",
      "1000/1000 [==============================] - 886s 886ms/step - loss: -0.7918 - jaccard_coef: 0.7918 - val_loss: -0.7626 - val_jaccard_coef: 0.7626\n",
      "\n",
      "Epoch 00154: loss did not improve from -0.79720\n",
      "Epoch 155/200\n",
      "1000/1000 [==============================] - 891s 891ms/step - loss: -0.7912 - jaccard_coef: 0.7912 - val_loss: -0.7567 - val_jaccard_coef: 0.7567\n",
      "\n",
      "Epoch 00155: loss did not improve from -0.79720\n",
      "Epoch 156/200\n",
      "1000/1000 [==============================] - 883s 883ms/step - loss: -0.7952 - jaccard_coef: 0.7952 - val_loss: -0.7935 - val_jaccard_coef: 0.7935\n",
      "\n",
      "Epoch 00156: loss did not improve from -0.79720\n",
      "Epoch 157/200\n",
      "1000/1000 [==============================] - 888s 888ms/step - loss: -0.7963 - jaccard_coef: 0.7963 - val_loss: -0.7824 - val_jaccard_coef: 0.7824\n",
      "\n",
      "Epoch 00157: loss did not improve from -0.79720\n",
      "Epoch 158/200\n",
      "1000/1000 [==============================] - 888s 888ms/step - loss: -0.7951 - jaccard_coef: 0.7951 - val_loss: -0.7838 - val_jaccard_coef: 0.7838\n",
      "\n",
      "Epoch 00158: loss did not improve from -0.79720\n",
      "Epoch 159/200\n",
      "1000/1000 [==============================] - 883s 883ms/step - loss: -0.8019 - jaccard_coef: 0.8019 - val_loss: -0.7769 - val_jaccard_coef: 0.7769\n",
      "\n",
      "Epoch 00159: loss improved from -0.79720 to -0.80184, saving model to unet_lesion.hdf5\n",
      "Epoch 160/200\n",
      "1000/1000 [==============================] - 885s 885ms/step - loss: -0.7969 - jaccard_coef: 0.7969 - val_loss: -0.7791 - val_jaccard_coef: 0.7791\n",
      "\n",
      "Epoch 00160: loss did not improve from -0.80184\n",
      "Epoch 161/200\n",
      "1000/1000 [==============================] - 880s 880ms/step - loss: -0.7952 - jaccard_coef: 0.7952 - val_loss: -0.7922 - val_jaccard_coef: 0.7922\n",
      "\n",
      "Epoch 00161: loss did not improve from -0.80184\n",
      "Epoch 162/200\n",
      "1000/1000 [==============================] - 883s 883ms/step - loss: -0.8020 - jaccard_coef: 0.8020 - val_loss: -0.7618 - val_jaccard_coef: 0.7618\n",
      "\n",
      "Epoch 00162: loss improved from -0.80184 to -0.80192, saving model to unet_lesion.hdf5\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 163/200\n",
      "1000/1000 [==============================] - 891s 891ms/step - loss: -0.7936 - jaccard_coef: 0.7936 - val_loss: -0.7959 - val_jaccard_coef: 0.7959\n",
      "\n",
      "Epoch 00163: loss did not improve from -0.80192\n",
      "Epoch 164/200\n",
      "1000/1000 [==============================] - 880s 880ms/step - loss: -0.8051 - jaccard_coef: 0.8051 - val_loss: -0.7824 - val_jaccard_coef: 0.7824\n",
      "\n",
      "Epoch 00164: loss improved from -0.80192 to -0.80505, saving model to unet_lesion.hdf5\n",
      "Epoch 165/200\n",
      "1000/1000 [==============================] - 890s 890ms/step - loss: -0.7959 - jaccard_coef: 0.7959 - val_loss: -0.7929 - val_jaccard_coef: 0.7929\n",
      "\n",
      "Epoch 00165: loss did not improve from -0.80505\n",
      "Epoch 166/200\n",
      "1000/1000 [==============================] - 892s 892ms/step - loss: -0.8013 - jaccard_coef: 0.8013 - val_loss: -0.7862 - val_jaccard_coef: 0.7862\n",
      "\n",
      "Epoch 00166: loss did not improve from -0.80505\n",
      "Epoch 167/200\n",
      "1000/1000 [==============================] - 888s 888ms/step - loss: -0.8042 - jaccard_coef: 0.8042 - val_loss: -0.7762 - val_jaccard_coef: 0.7762\n",
      "\n",
      "Epoch 00167: loss did not improve from -0.80505\n",
      "Epoch 168/200\n",
      "1000/1000 [==============================] - 895s 895ms/step - loss: -0.8017 - jaccard_coef: 0.8017 - val_loss: -0.7728 - val_jaccard_coef: 0.7728\n",
      "\n",
      "Epoch 00168: loss did not improve from -0.80505\n",
      "Epoch 169/200\n",
      "1000/1000 [==============================] - 890s 890ms/step - loss: -0.8076 - jaccard_coef: 0.8076 - val_loss: -0.7899 - val_jaccard_coef: 0.7899\n",
      "\n",
      "Epoch 00169: loss improved from -0.80505 to -0.80777, saving model to unet_lesion.hdf5\n",
      "Epoch 170/200\n",
      "1000/1000 [==============================] - 874s 874ms/step - loss: -0.7997 - jaccard_coef: 0.7997 - val_loss: -0.7696 - val_jaccard_coef: 0.7696\n",
      "\n",
      "Epoch 00170: loss did not improve from -0.80777\n",
      "Epoch 171/200\n",
      "1000/1000 [==============================] - 892s 892ms/step - loss: -0.8005 - jaccard_coef: 0.8005 - val_loss: -0.7769 - val_jaccard_coef: 0.7769\n",
      "\n",
      "Epoch 00171: loss did not improve from -0.80777\n",
      "Epoch 172/200\n",
      "1000/1000 [==============================] - 876s 876ms/step - loss: -0.8003 - jaccard_coef: 0.8003 - val_loss: -0.7746 - val_jaccard_coef: 0.7746\n",
      "\n",
      "Epoch 00172: loss did not improve from -0.80777\n",
      "Epoch 173/200\n",
      "1000/1000 [==============================] - 900s 900ms/step - loss: -0.8048 - jaccard_coef: 0.8048 - val_loss: -0.7720 - val_jaccard_coef: 0.7720\n",
      "\n",
      "Epoch 00173: loss did not improve from -0.80777\n",
      "Epoch 174/200\n",
      "1000/1000 [==============================] - 873s 873ms/step - loss: -0.8031 - jaccard_coef: 0.8031 - val_loss: -0.7933 - val_jaccard_coef: 0.7933\n",
      "\n",
      "Epoch 00174: loss did not improve from -0.80777\n",
      "Epoch 175/200\n",
      "1000/1000 [==============================] - 892s 892ms/step - loss: -0.8091 - jaccard_coef: 0.8091 - val_loss: -0.7906 - val_jaccard_coef: 0.7906\n",
      "\n",
      "Epoch 00175: loss improved from -0.80777 to -0.80896, saving model to unet_lesion.hdf5\n",
      "Epoch 176/200\n",
      "1000/1000 [==============================] - 881s 881ms/step - loss: -0.8056 - jaccard_coef: 0.8056 - val_loss: -0.7860 - val_jaccard_coef: 0.7860\n",
      "\n",
      "Epoch 00176: loss did not improve from -0.80896\n",
      "Epoch 177/200\n",
      "1000/1000 [==============================] - 879s 879ms/step - loss: -0.8096 - jaccard_coef: 0.8096 - val_loss: -0.7934 - val_jaccard_coef: 0.7934\n",
      "\n",
      "Epoch 00177: loss improved from -0.80896 to -0.80953, saving model to unet_lesion.hdf5\n",
      "Epoch 178/200\n",
      "1000/1000 [==============================] - 901s 901ms/step - loss: -0.8081 - jaccard_coef: 0.8081 - val_loss: -0.7942 - val_jaccard_coef: 0.7942\n",
      "\n",
      "Epoch 00178: loss did not improve from -0.80953\n",
      "Epoch 179/200\n",
      "1000/1000 [==============================] - 880s 880ms/step - loss: -0.8034 - jaccard_coef: 0.8034 - val_loss: -0.7635 - val_jaccard_coef: 0.7635\n",
      "\n",
      "Epoch 00179: loss did not improve from -0.80953\n",
      "Epoch 180/200\n",
      "1000/1000 [==============================] - 912s 912ms/step - loss: -0.8100 - jaccard_coef: 0.8100 - val_loss: -0.7663 - val_jaccard_coef: 0.7663\n",
      "\n",
      "Epoch 00180: loss improved from -0.80953 to -0.81002, saving model to unet_lesion.hdf5\n",
      "Epoch 181/200\n",
      "1000/1000 [==============================] - 893s 893ms/step - loss: -0.8082 - jaccard_coef: 0.8082 - val_loss: -0.7901 - val_jaccard_coef: 0.7901\n",
      "\n",
      "Epoch 00181: loss did not improve from -0.81002\n",
      "Epoch 182/200\n",
      "1000/1000 [==============================] - 888s 888ms/step - loss: -0.8050 - jaccard_coef: 0.8050 - val_loss: -0.7999 - val_jaccard_coef: 0.7999\n",
      "\n",
      "Epoch 00182: loss did not improve from -0.81002\n",
      "Epoch 183/200\n",
      "1000/1000 [==============================] - 881s 881ms/step - loss: -0.8067 - jaccard_coef: 0.8067 - val_loss: -0.7847 - val_jaccard_coef: 0.7847\n",
      "\n",
      "Epoch 00183: loss did not improve from -0.81002\n",
      "Epoch 184/200\n",
      "1000/1000 [==============================] - 888s 888ms/step - loss: -0.8083 - jaccard_coef: 0.8083 - val_loss: -0.7917 - val_jaccard_coef: 0.7917\n",
      "\n",
      "Epoch 00184: loss did not improve from -0.81002\n",
      "Epoch 185/200\n",
      "1000/1000 [==============================] - 886s 886ms/step - loss: -0.8110 - jaccard_coef: 0.8110 - val_loss: -0.7860 - val_jaccard_coef: 0.7860\n",
      "\n",
      "Epoch 00185: loss improved from -0.81002 to -0.81140, saving model to unet_lesion.hdf5\n",
      "Epoch 186/200\n",
      "1000/1000 [==============================] - 898s 898ms/step - loss: -0.8157 - jaccard_coef: 0.8157 - val_loss: -0.7955 - val_jaccard_coef: 0.7955\n",
      "\n",
      "Epoch 00186: loss improved from -0.81140 to -0.81558, saving model to unet_lesion.hdf5\n",
      "Epoch 187/200\n",
      "1000/1000 [==============================] - 888s 888ms/step - loss: -0.8073 - jaccard_coef: 0.8073 - val_loss: -0.7962 - val_jaccard_coef: 0.7962\n",
      "\n",
      "Epoch 00187: loss did not improve from -0.81558\n",
      "Epoch 188/200\n",
      "1000/1000 [==============================] - 877s 877ms/step - loss: -0.8117 - jaccard_coef: 0.8117 - val_loss: -0.7890 - val_jaccard_coef: 0.7890\n",
      "\n",
      "Epoch 00188: loss did not improve from -0.81558\n",
      "Epoch 189/200\n",
      "1000/1000 [==============================] - 894s 894ms/step - loss: -0.8107 - jaccard_coef: 0.8107 - val_loss: -0.7814 - val_jaccard_coef: 0.7814\n",
      "\n",
      "Epoch 00189: loss did not improve from -0.81558\n",
      "Epoch 190/200\n",
      "1000/1000 [==============================] - 881s 881ms/step - loss: -0.8150 - jaccard_coef: 0.8150 - val_loss: -0.7978 - val_jaccard_coef: 0.7978\n",
      "\n",
      "Epoch 00190: loss did not improve from -0.81558\n",
      "Epoch 191/200\n",
      "1000/1000 [==============================] - 896s 896ms/step - loss: -0.8124 - jaccard_coef: 0.8124 - val_loss: -0.7925 - val_jaccard_coef: 0.7925\n",
      "\n",
      "Epoch 00191: loss did not improve from -0.81558\n",
      "Epoch 192/200\n",
      "1000/1000 [==============================] - 891s 891ms/step - loss: -0.8121 - jaccard_coef: 0.8121 - val_loss: -0.7856 - val_jaccard_coef: 0.7856\n",
      "\n",
      "Epoch 00192: loss did not improve from -0.81558\n",
      "Epoch 193/200\n",
      "1000/1000 [==============================] - 877s 877ms/step - loss: -0.8129 - jaccard_coef: 0.8129 - val_loss: -0.7910 - val_jaccard_coef: 0.7910\n",
      "\n",
      "Epoch 00193: loss did not improve from -0.81558\n",
      "Epoch 194/200\n",
      "1000/1000 [==============================] - 884s 884ms/step - loss: -0.8161 - jaccard_coef: 0.8161 - val_loss: -0.7925 - val_jaccard_coef: 0.7925\n",
      "\n",
      "Epoch 00194: loss improved from -0.81558 to -0.81610, saving model to unet_lesion.hdf5\n",
      "Epoch 195/200\n",
      "1000/1000 [==============================] - 876s 876ms/step - loss: -0.8102 - jaccard_coef: 0.8102 - val_loss: -0.7836 - val_jaccard_coef: 0.7836\n",
      "\n",
      "Epoch 00195: loss did not improve from -0.81610\n",
      "Epoch 196/200\n",
      "1000/1000 [==============================] - 893s 893ms/step - loss: -0.8162 - jaccard_coef: 0.8162 - val_loss: -0.7767 - val_jaccard_coef: 0.7767\n",
      "\n",
      "Epoch 00196: loss did not improve from -0.81610\n",
      "Epoch 197/200\n",
      "1000/1000 [==============================] - 878s 878ms/step - loss: -0.8098 - jaccard_coef: 0.8098 - val_loss: -0.7766 - val_jaccard_coef: 0.7766\n",
      "\n",
      "Epoch 00197: loss did not improve from -0.81610\n",
      "Epoch 198/200\n",
      "1000/1000 [==============================] - 881s 881ms/step - loss: -0.8142 - jaccard_coef: 0.8142 - val_loss: -0.7603 - val_jaccard_coef: 0.7603\n",
      "\n",
      "Epoch 00198: loss did not improve from -0.81610\n",
      "Epoch 199/200\n",
      "1000/1000 [==============================] - 892s 892ms/step - loss: -0.8145 - jaccard_coef: 0.8145 - val_loss: -0.7838 - val_jaccard_coef: 0.7838\n",
      "\n",
      "Epoch 00199: loss did not improve from -0.81610\n",
      "Epoch 200/200\n",
      "1000/1000 [==============================] - 871s 871ms/step - loss: -0.8195 - jaccard_coef: 0.8195 - val_loss: -0.8016 - val_jaccard_coef: 0.8016\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Epoch 00200: loss improved from -0.81610 to -0.81969, saving model to unet_lesion.hdf5\n"
     ]
    }
   ],
   "source": [
    "#Continue traing\n",
    "#Use initial_epoch \n",
    "\n",
    "history2 = model.fit_generator(\n",
    "    myGene,\n",
    "    steps_per_epoch = 1000, \n",
    "    epochs=200,\n",
    "    callbacks=[model_checkpoint,tensorBoard], \n",
    "    initial_epoch = 125,\n",
    "    validation_data=myValGene,\n",
    "    validation_steps=200)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plot training & validation accuracy values\n",
    "plt.plot(history.history['jaccard_coef'])\n",
    "plt.plot(history.history['val_jaccard_coef'])\n",
    "plt.title('Coefficiency')\n",
    "plt.ylabel('Coefficiency')\n",
    "plt.xlabel('Epoch')\n",
    "plt.legend(['Train'], loc='upper left')\n",
    "plt.legend(['Validation'], loc='upper left')\n",
    "plt.show()\n",
    "\n",
    "# Plot training & validation loss values\n",
    "plt.plot(history.history['loss'])\n",
    "plt.plot(history.history['val_loss'])\n",
    "plt.title('Model loss')\n",
    "plt.ylabel('Loss')\n",
    "plt.xlabel('Epoch')\n",
    "plt.legend(['Train'], loc='upper left')\n",
    "plt.legend(['Validation'], loc='upper left')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\li_ni\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:63: UserWarning: Update your `Model` call to the Keras 2 API: `Model(inputs=Tensor(\"in..., outputs=Tensor(\"co...)`\n"
     ]
    }
   ],
   "source": [
    "file_names = next(os.walk(test_data_dir))[2]\n",
    "\n",
    "model = LeakyUnetModelBig()\n",
    "model.load_weights(\"unet_lesion.hdf5\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on Model in module keras.engine.training object:\n",
      "\n",
      "class Model(keras.engine.network.Network)\n",
      " |  Model(*args, **kwargs)\n",
      " |  \n",
      " |  The `Model` class adds training & evaluation routines to a `Network`.\n",
      " |  \n",
      " |  Method resolution order:\n",
      " |      Model\n",
      " |      keras.engine.network.Network\n",
      " |      keras.engine.base_layer.Layer\n",
      " |      builtins.object\n",
      " |  \n",
      " |  Methods defined here:\n",
      " |  \n",
      " |  compile(self, optimizer, loss=None, metrics=None, loss_weights=None, sample_weight_mode=None, weighted_metrics=None, target_tensors=None, **kwargs)\n",
      " |      Configures the model for training.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          optimizer: String (name of optimizer) or optimizer instance.\n",
      " |              See [optimizers](/optimizers).\n",
      " |          loss: String (name of objective function) or objective function.\n",
      " |              See [losses](/losses).\n",
      " |              If the model has multiple outputs, you can use a different loss\n",
      " |              on each output by passing a dictionary or a list of losses.\n",
      " |              The loss value that will be minimized by the model\n",
      " |              will then be the sum of all individual losses.\n",
      " |          metrics: List of metrics to be evaluated by the model\n",
      " |              during training and testing.\n",
      " |              Typically you will use `metrics=['accuracy']`.\n",
      " |              To specify different metrics for different outputs of a\n",
      " |              multi-output model, you could also pass a dictionary,\n",
      " |              such as `metrics={'output_a': 'accuracy'}`.\n",
      " |          loss_weights: Optional list or dictionary specifying scalar\n",
      " |              coefficients (Python floats) to weight the loss contributions\n",
      " |              of different model outputs.\n",
      " |              The loss value that will be minimized by the model\n",
      " |              will then be the *weighted sum* of all individual losses,\n",
      " |              weighted by the `loss_weights` coefficients.\n",
      " |              If a list, it is expected to have a 1:1 mapping\n",
      " |              to the model's outputs. If a tensor, it is expected to map\n",
      " |              output names (strings) to scalar coefficients.\n",
      " |          sample_weight_mode: If you need to do timestep-wise\n",
      " |              sample weighting (2D weights), set this to `\"temporal\"`.\n",
      " |              `None` defaults to sample-wise weights (1D).\n",
      " |              If the model has multiple outputs, you can use a different\n",
      " |              `sample_weight_mode` on each output by passing a\n",
      " |              dictionary or a list of modes.\n",
      " |          weighted_metrics: List of metrics to be evaluated and weighted\n",
      " |              by sample_weight or class_weight during training and testing.\n",
      " |          target_tensors: By default, Keras will create placeholders for the\n",
      " |              model's target, which will be fed with the target data during\n",
      " |              training. If instead you would like to use your own\n",
      " |              target tensors (in turn, Keras will not expect external\n",
      " |              Numpy data for these targets at training time), you\n",
      " |              can specify them via the `target_tensors` argument. It can be\n",
      " |              a single tensor (for a single-output model), a list of tensors,\n",
      " |              or a dict mapping output names to target tensors.\n",
      " |          **kwargs: When using the Theano/CNTK backends, these arguments\n",
      " |              are passed into `K.function`.\n",
      " |              When using the TensorFlow backend,\n",
      " |              these arguments are passed into `tf.Session.run`.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: In case of invalid arguments for\n",
      " |              `optimizer`, `loss`, `metrics` or `sample_weight_mode`.\n",
      " |  \n",
      " |  evaluate(self, x=None, y=None, batch_size=None, verbose=1, sample_weight=None, steps=None)\n",
      " |      Returns the loss value & metrics values for the model in test mode.\n",
      " |      \n",
      " |      Computation is done in batches.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          x: Numpy array of test data (if the model has a single input),\n",
      " |              or list of Numpy arrays (if the model has multiple inputs).\n",
      " |              If input layers in the model are named, you can also pass a\n",
      " |              dictionary mapping input names to Numpy arrays.\n",
      " |              `x` can be `None` (default) if feeding from\n",
      " |              framework-native tensors (e.g. TensorFlow data tensors).\n",
      " |          y: Numpy array of target (label) data\n",
      " |              (if the model has a single output),\n",
      " |              or list of Numpy arrays (if the model has multiple outputs).\n",
      " |              If output layers in the model are named, you can also pass a\n",
      " |              dictionary mapping output names to Numpy arrays.\n",
      " |              `y` can be `None` (default) if feeding from\n",
      " |              framework-native tensors (e.g. TensorFlow data tensors).\n",
      " |          batch_size: Integer or `None`.\n",
      " |              Number of samples per evaluation step.\n",
      " |              If unspecified, `batch_size` will default to 32.\n",
      " |          verbose: 0 or 1. Verbosity mode.\n",
      " |              0 = silent, 1 = progress bar.\n",
      " |          sample_weight: Optional Numpy array of weights for\n",
      " |              the test samples, used for weighting the loss function.\n",
      " |              You can either pass a flat (1D)\n",
      " |              Numpy array with the same length as the input samples\n",
      " |              (1:1 mapping between weights and samples),\n",
      " |              or in the case of temporal data,\n",
      " |              you can pass a 2D array with shape\n",
      " |              `(samples, sequence_length)`,\n",
      " |              to apply a different weight to every timestep of every sample.\n",
      " |              In this case you should make sure to specify\n",
      " |              `sample_weight_mode=\"temporal\"` in `compile()`.\n",
      " |          steps: Integer or `None`.\n",
      " |              Total number of steps (batches of samples)\n",
      " |              before declaring the evaluation round finished.\n",
      " |              Ignored with the default value of `None`.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Scalar test loss (if the model has a single output and no metrics)\n",
      " |          or list of scalars (if the model has multiple outputs\n",
      " |          and/or metrics). The attribute `model.metrics_names` will give you\n",
      " |          the display labels for the scalar outputs.\n",
      " |  \n",
      " |  evaluate_generator(self, generator, steps=None, max_queue_size=10, workers=1, use_multiprocessing=False, verbose=0)\n",
      " |      Evaluates the model on a data generator.\n",
      " |      \n",
      " |      The generator should return the same kind of data\n",
      " |      as accepted by `test_on_batch`.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          generator: Generator yielding tuples (inputs, targets)\n",
      " |              or (inputs, targets, sample_weights)\n",
      " |              or an instance of Sequence (keras.utils.Sequence)\n",
      " |              object in order to avoid duplicate data\n",
      " |              when using multiprocessing.\n",
      " |          steps: Total number of steps (batches of samples)\n",
      " |              to yield from `generator` before stopping.\n",
      " |              Optional for `Sequence`: if unspecified, will use\n",
      " |              the `len(generator)` as a number of steps.\n",
      " |          max_queue_size: maximum size for the generator queue\n",
      " |          workers: Integer. Maximum number of processes to spin up\n",
      " |              when using process based threading.\n",
      " |              If unspecified, `workers` will default to 1. If 0, will\n",
      " |              execute the generator on the main thread.\n",
      " |          use_multiprocessing: if True, use process based threading.\n",
      " |              Note that because\n",
      " |              this implementation relies on multiprocessing,\n",
      " |              you should not pass\n",
      " |              non picklable arguments to the generator\n",
      " |              as they can't be passed\n",
      " |              easily to children processes.\n",
      " |          verbose: verbosity mode, 0 or 1.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Scalar test loss (if the model has a single output and no metrics)\n",
      " |          or list of scalars (if the model has multiple outputs\n",
      " |          and/or metrics). The attribute `model.metrics_names` will give you\n",
      " |          the display labels for the scalar outputs.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: In case the generator yields\n",
      " |              data in an invalid format.\n",
      " |  \n",
      " |  fit(self, x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None, **kwargs)\n",
      " |      Trains the model for a given number of epochs (iterations on a dataset).\n",
      " |      \n",
      " |      # Arguments\n",
      " |          x: Numpy array of training data (if the model has a single input),\n",
      " |              or list of Numpy arrays (if the model has multiple inputs).\n",
      " |              If input layers in the model are named, you can also pass a\n",
      " |              dictionary mapping input names to Numpy arrays.\n",
      " |              `x` can be `None` (default) if feeding from\n",
      " |              framework-native tensors (e.g. TensorFlow data tensors).\n",
      " |          y: Numpy array of target (label) data\n",
      " |              (if the model has a single output),\n",
      " |              or list of Numpy arrays (if the model has multiple outputs).\n",
      " |              If output layers in the model are named, you can also pass a\n",
      " |              dictionary mapping output names to Numpy arrays.\n",
      " |              `y` can be `None` (default) if feeding from\n",
      " |              framework-native tensors (e.g. TensorFlow data tensors).\n",
      " |          batch_size: Integer or `None`.\n",
      " |              Number of samples per gradient update.\n",
      " |              If unspecified, `batch_size` will default to 32.\n",
      " |          epochs: Integer. Number of epochs to train the model.\n",
      " |              An epoch is an iteration over the entire `x` and `y`\n",
      " |              data provided.\n",
      " |              Note that in conjunction with `initial_epoch`,\n",
      " |              `epochs` is to be understood as \"final epoch\".\n",
      " |              The model is not trained for a number of iterations\n",
      " |              given by `epochs`, but merely until the epoch\n",
      " |              of index `epochs` is reached.\n",
      " |          verbose: Integer. 0, 1, or 2. Verbosity mode.\n",
      " |              0 = silent, 1 = progress bar, 2 = one line per epoch.\n",
      " |          callbacks: List of `keras.callbacks.Callback` instances.\n",
      " |              List of callbacks to apply during training.\n",
      " |              See [callbacks](/callbacks).\n",
      " |          validation_split: Float between 0 and 1.\n",
      " |              Fraction of the training data to be used as validation data.\n",
      " |              The model will set apart this fraction of the training data,\n",
      " |              will not train on it, and will evaluate\n",
      " |              the loss and any model metrics\n",
      " |              on this data at the end of each epoch.\n",
      " |              The validation data is selected from the last samples\n",
      " |              in the `x` and `y` data provided, before shuffling.\n",
      " |          validation_data: tuple `(x_val, y_val)` or tuple\n",
      " |              `(x_val, y_val, val_sample_weights)` on which to evaluate\n",
      " |              the loss and any model metrics at the end of each epoch.\n",
      " |              The model will not be trained on this data.\n",
      " |              `validation_data` will override `validation_split`.\n",
      " |          shuffle: Boolean (whether to shuffle the training data\n",
      " |              before each epoch) or str (for 'batch').\n",
      " |              'batch' is a special option for dealing with the\n",
      " |              limitations of HDF5 data; it shuffles in batch-sized chunks.\n",
      " |              Has no effect when `steps_per_epoch` is not `None`.\n",
      " |          class_weight: Optional dictionary mapping class indices (integers)\n",
      " |              to a weight (float) value, used for weighting the loss function\n",
      " |              (during training only).\n",
      " |              This can be useful to tell the model to\n",
      " |              \"pay more attention\" to samples from\n",
      " |              an under-represented class.\n",
      " |          sample_weight: Optional Numpy array of weights for\n",
      " |              the training samples, used for weighting the loss function\n",
      " |              (during training only). You can either pass a flat (1D)\n",
      " |              Numpy array with the same length as the input samples\n",
      " |              (1:1 mapping between weights and samples),\n",
      " |              or in the case of temporal data,\n",
      " |              you can pass a 2D array with shape\n",
      " |              `(samples, sequence_length)`,\n",
      " |              to apply a different weight to every timestep of every sample.\n",
      " |              In this case you should make sure to specify\n",
      " |              `sample_weight_mode=\"temporal\"` in `compile()`.\n",
      " |          initial_epoch: Integer.\n",
      " |              Epoch at which to start training\n",
      " |              (useful for resuming a previous training run).\n",
      " |          steps_per_epoch: Integer or `None`.\n",
      " |              Total number of steps (batches of samples)\n",
      " |              before declaring one epoch finished and starting the\n",
      " |              next epoch. When training with input tensors such as\n",
      " |              TensorFlow data tensors, the default `None` is equal to\n",
      " |              the number of samples in your dataset divided by\n",
      " |              the batch size, or 1 if that cannot be determined.\n",
      " |          validation_steps: Only relevant if `steps_per_epoch`\n",
      " |              is specified. Total number of steps (batches of samples)\n",
      " |              to validate before stopping.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A `History` object. Its `History.history` attribute is\n",
      " |          a record of training loss values and metrics values\n",
      " |          at successive epochs, as well as validation loss values\n",
      " |          and validation metrics values (if applicable).\n",
      " |      \n",
      " |      # Raises\n",
      " |          RuntimeError: If the model was never compiled.\n",
      " |          ValueError: In case of mismatch between the provided input data\n",
      " |              and what the model expects.\n",
      " |  \n",
      " |  fit_generator(self, generator, steps_per_epoch=None, epochs=1, verbose=1, callbacks=None, validation_data=None, validation_steps=None, class_weight=None, max_queue_size=10, workers=1, use_multiprocessing=False, shuffle=True, initial_epoch=0)\n",
      " |      Trains the model on data generated batch-by-batch by a Python generator\n",
      " |      (or an instance of `Sequence`).\n",
      " |      \n",
      " |      The generator is run in parallel to the model, for efficiency.\n",
      " |      For instance, this allows you to do real-time data augmentation\n",
      " |      on images on CPU in parallel to training your model on GPU.\n",
      " |      \n",
      " |      The use of `keras.utils.Sequence` guarantees the ordering\n",
      " |      and guarantees the single use of every input per epoch when\n",
      " |      using `use_multiprocessing=True`.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          generator: A generator or an instance of `Sequence`\n",
      " |              (`keras.utils.Sequence`) object in order to avoid\n",
      " |              duplicate data when using multiprocessing.\n",
      " |              The output of the generator must be either\n",
      " |              - a tuple `(inputs, targets)`\n",
      " |              - a tuple `(inputs, targets, sample_weights)`.\n",
      " |              This tuple (a single output of the generator) makes a single\n",
      " |              batch. Therefore, all arrays in this tuple must have the same\n",
      " |              length (equal to the size of this batch). Different batches may\n",
      " |              have different sizes. For example, the last batch of the epoch\n",
      " |              is commonly smaller than the others, if the size of the dataset\n",
      " |              is not divisible by the batch size.\n",
      " |              The generator is expected to loop over its data\n",
      " |              indefinitely. An epoch finishes when `steps_per_epoch`\n",
      " |              batches have been seen by the model.\n",
      " |          steps_per_epoch: Integer.\n",
      " |              Total number of steps (batches of samples)\n",
      " |              to yield from `generator` before declaring one epoch\n",
      " |              finished and starting the next epoch. It should typically\n",
      " |              be equal to the number of samples of your dataset\n",
      " |              divided by the batch size.\n",
      " |              Optional for `Sequence`: if unspecified, will use\n",
      " |              the `len(generator)` as a number of steps.\n",
      " |          epochs: Integer. Number of epochs to train the model.\n",
      " |              An epoch is an iteration over the entire data provided,\n",
      " |              as defined by `steps_per_epoch`.\n",
      " |              Note that in conjunction with `initial_epoch`,\n",
      " |              `epochs` is to be understood as \"final epoch\".\n",
      " |              The model is not trained for a number of iterations\n",
      " |              given by `epochs`, but merely until the epoch\n",
      " |              of index `epochs` is reached.\n",
      " |          verbose: Integer. 0, 1, or 2. Verbosity mode.\n",
      " |              0 = silent, 1 = progress bar, 2 = one line per epoch.\n",
      " |          callbacks: List of `keras.callbacks.Callback` instances.\n",
      " |              List of callbacks to apply during training.\n",
      " |              See [callbacks](/callbacks).\n",
      " |          validation_data: This can be either\n",
      " |              - a generator or a `Sequence` object for the validation data\n",
      " |              - tuple `(x_val, y_val)`\n",
      " |              - tuple `(x_val, y_val, val_sample_weights)`\n",
      " |              on which to evaluate\n",
      " |              the loss and any model metrics at the end of each epoch.\n",
      " |              The model will not be trained on this data.\n",
      " |          validation_steps: Only relevant if `validation_data`\n",
      " |              is a generator. Total number of steps (batches of samples)\n",
      " |              to yield from `validation_data` generator before stopping\n",
      " |              at the end of every epoch. It should typically\n",
      " |              be equal to the number of samples of your\n",
      " |              validation dataset divided by the batch size.\n",
      " |              Optional for `Sequence`: if unspecified, will use\n",
      " |              the `len(validation_data)` as a number of steps.\n",
      " |          class_weight: Optional dictionary mapping class indices (integers)\n",
      " |              to a weight (float) value, used for weighting the loss function\n",
      " |              (during training only). This can be useful to tell the model to\n",
      " |              \"pay more attention\" to samples\n",
      " |              from an under-represented class.\n",
      " |          max_queue_size: Integer. Maximum size for the generator queue.\n",
      " |              If unspecified, `max_queue_size` will default to 10.\n",
      " |          workers: Integer. Maximum number of processes to spin up\n",
      " |              when using process-based threading.\n",
      " |              If unspecified, `workers` will default to 1. If 0, will\n",
      " |              execute the generator on the main thread.\n",
      " |          use_multiprocessing: Boolean.\n",
      " |              If `True`, use process-based threading.\n",
      " |              If unspecified, `use_multiprocessing` will default to `False`.\n",
      " |              Note that because this implementation\n",
      " |              relies on multiprocessing,\n",
      " |              you should not pass non-picklable arguments to the generator\n",
      " |              as they can't be passed easily to children processes.\n",
      " |          shuffle: Boolean. Whether to shuffle the order of the batches at\n",
      " |              the beginning of each epoch. Only used with instances\n",
      " |              of `Sequence` (`keras.utils.Sequence`).\n",
      " |              Has no effect when `steps_per_epoch` is not `None`.\n",
      " |          initial_epoch: Integer.\n",
      " |              Epoch at which to start training\n",
      " |              (useful for resuming a previous training run).\n",
      " |      \n",
      " |      # Returns\n",
      " |          A `History` object. Its `History.history` attribute is\n",
      " |          a record of training loss values and metrics values\n",
      " |          at successive epochs, as well as validation loss values\n",
      " |          and validation metrics values (if applicable).\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: In case the generator yields data in an invalid format.\n",
      " |      \n",
      " |      # Example\n",
      " |      \n",
      " |      ```python\n",
      " |      def generate_arrays_from_file(path):\n",
      " |          while True:\n",
      " |              with open(path) as f:\n",
      " |                  for line in f:\n",
      " |                      # create numpy arrays of input data\n",
      " |                      # and labels, from each line in the file\n",
      " |                      x1, x2, y = process_line(line)\n",
      " |                      yield ({'input_1': x1, 'input_2': x2}, {'output': y})\n",
      " |      \n",
      " |      model.fit_generator(generate_arrays_from_file('/my_file.txt'),\n",
      " |                          steps_per_epoch=10000, epochs=10)\n",
      " |      ```\n",
      " |  \n",
      " |  predict(self, x, batch_size=None, verbose=0, steps=None)\n",
      " |      Generates output predictions for the input samples.\n",
      " |      \n",
      " |      Computation is done in batches.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          x: The input data, as a Numpy array\n",
      " |              (or list of Numpy arrays if the model has multiple inputs).\n",
      " |          batch_size: Integer. If unspecified, it will default to 32.\n",
      " |          verbose: Verbosity mode, 0 or 1.\n",
      " |          steps: Total number of steps (batches of samples)\n",
      " |              before declaring the prediction round finished.\n",
      " |              Ignored with the default value of `None`.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Numpy array(s) of predictions.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: In case of mismatch between the provided\n",
      " |              input data and the model's expectations,\n",
      " |              or in case a stateful model receives a number of samples\n",
      " |              that is not a multiple of the batch size.\n",
      " |  \n",
      " |  predict_generator(self, generator, steps=None, max_queue_size=10, workers=1, use_multiprocessing=False, verbose=0)\n",
      " |      Generates predictions for the input samples from a data generator.\n",
      " |      \n",
      " |      The generator should return the same kind of data as accepted by\n",
      " |      `predict_on_batch`.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          generator: Generator yielding batches of input samples\n",
      " |              or an instance of Sequence (keras.utils.Sequence)\n",
      " |              object in order to avoid duplicate data\n",
      " |              when using multiprocessing.\n",
      " |          steps: Total number of steps (batches of samples)\n",
      " |              to yield from `generator` before stopping.\n",
      " |              Optional for `Sequence`: if unspecified, will use\n",
      " |              the `len(generator)` as a number of steps.\n",
      " |          max_queue_size: Maximum size for the generator queue.\n",
      " |          workers: Integer. Maximum number of processes to spin up\n",
      " |              when using process based threading.\n",
      " |              If unspecified, `workers` will default to 1. If 0, will\n",
      " |              execute the generator on the main thread.\n",
      " |          use_multiprocessing: If `True`, use process based threading.\n",
      " |              Note that because\n",
      " |              this implementation relies on multiprocessing,\n",
      " |              you should not pass\n",
      " |              non picklable arguments to the generator\n",
      " |              as they can't be passed\n",
      " |              easily to children processes.\n",
      " |          verbose: verbosity mode, 0 or 1.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Numpy array(s) of predictions.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: In case the generator yields\n",
      " |              data in an invalid format.\n",
      " |  \n",
      " |  predict_on_batch(self, x)\n",
      " |      Returns predictions for a single batch of samples.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          x: Input samples, as a Numpy array.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Numpy array(s) of predictions.\n",
      " |  \n",
      " |  test_on_batch(self, x, y, sample_weight=None)\n",
      " |      Test the model on a single batch of samples.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          x: Numpy array of test data,\n",
      " |              or list of Numpy arrays if the model has multiple inputs.\n",
      " |              If all inputs in the model are named,\n",
      " |              you can also pass a dictionary\n",
      " |              mapping input names to Numpy arrays.\n",
      " |          y: Numpy array of target data,\n",
      " |              or list of Numpy arrays if the model has multiple outputs.\n",
      " |              If all outputs in the model are named,\n",
      " |              you can also pass a dictionary\n",
      " |              mapping output names to Numpy arrays.\n",
      " |          sample_weight: Optional array of the same length as x, containing\n",
      " |              weights to apply to the model's loss for each sample.\n",
      " |              In the case of temporal data, you can pass a 2D array\n",
      " |              with shape (samples, sequence_length),\n",
      " |              to apply a different weight to every timestep of every sample.\n",
      " |              In this case you should make sure to specify\n",
      " |              sample_weight_mode=\"temporal\" in compile().\n",
      " |      \n",
      " |      # Returns\n",
      " |          Scalar test loss (if the model has a single output and no metrics)\n",
      " |          or list of scalars (if the model has multiple outputs\n",
      " |          and/or metrics). The attribute `model.metrics_names` will give you\n",
      " |          the display labels for the scalar outputs.\n",
      " |  \n",
      " |  train_on_batch(self, x, y, sample_weight=None, class_weight=None)\n",
      " |      Runs a single gradient update on a single batch of data.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          x: Numpy array of training data,\n",
      " |              or list of Numpy arrays if the model has multiple inputs.\n",
      " |              If all inputs in the model are named,\n",
      " |              you can also pass a dictionary\n",
      " |              mapping input names to Numpy arrays.\n",
      " |          y: Numpy array of target data,\n",
      " |              or list of Numpy arrays if the model has multiple outputs.\n",
      " |              If all outputs in the model are named,\n",
      " |              you can also pass a dictionary\n",
      " |              mapping output names to Numpy arrays.\n",
      " |          sample_weight: Optional array of the same length as x, containing\n",
      " |              weights to apply to the model's loss for each sample.\n",
      " |              In the case of temporal data, you can pass a 2D array\n",
      " |              with shape (samples, sequence_length),\n",
      " |              to apply a different weight to every timestep of every sample.\n",
      " |              In this case you should make sure to specify\n",
      " |              sample_weight_mode=\"temporal\" in compile().\n",
      " |          class_weight: Optional dictionary mapping\n",
      " |              class indices (integers) to\n",
      " |              a weight (float) to apply to the model's loss for the samples\n",
      " |              from this class during training.\n",
      " |              This can be useful to tell the model to \"pay more attention\" to\n",
      " |              samples from an under-represented class.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Scalar training loss\n",
      " |          (if the model has a single output and no metrics)\n",
      " |          or list of scalars (if the model has multiple outputs\n",
      " |          and/or metrics). The attribute `model.metrics_names` will give you\n",
      " |          the display labels for the scalar outputs.\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Methods inherited from keras.engine.network.Network:\n",
      " |  \n",
      " |  __getstate__(self)\n",
      " |  \n",
      " |  __init__(self, *args, **kwargs)\n",
      " |      Initialize self.  See help(type(self)) for accurate signature.\n",
      " |  \n",
      " |  __setattr__(self, name, value)\n",
      " |      Implement setattr(self, name, value).\n",
      " |  \n",
      " |  __setstate__(self, state)\n",
      " |  \n",
      " |  call(self, inputs, mask=None)\n",
      " |      Calls the model on new inputs.\n",
      " |      \n",
      " |      In this case `call` just reapplies\n",
      " |      all ops in the graph to the new inputs\n",
      " |      (e.g. build a new computational graph from the provided inputs).\n",
      " |      \n",
      " |      A model is callable on non-Keras tensors.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          inputs: A tensor or list of tensors.\n",
      " |          mask: A mask or list of masks. A mask can be\n",
      " |              either a tensor or None (no mask).\n",
      " |      \n",
      " |      # Returns\n",
      " |          A tensor if there is a single output, or\n",
      " |          a list of tensors if there are more than one outputs.\n",
      " |  \n",
      " |  compute_mask(self, inputs, mask)\n",
      " |      Computes an output mask tensor.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          inputs: Tensor or list of tensors.\n",
      " |          mask: Tensor or list of tensors.\n",
      " |      \n",
      " |      # Returns\n",
      " |          None or a tensor (or list of tensors,\n",
      " |              one per output tensor of the layer).\n",
      " |  \n",
      " |  compute_output_shape(self, input_shape)\n",
      " |      Computes the output shape of the layer.\n",
      " |      \n",
      " |      Assumes that the layer will be built\n",
      " |      to match that input shape provided.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          input_shape: Shape tuple (tuple of integers)\n",
      " |              or list of shape tuples (one per output tensor of the layer).\n",
      " |              Shape tuples can include None for free dimensions,\n",
      " |              instead of an integer.\n",
      " |      \n",
      " |      # Returns\n",
      " |          An input shape tuple.\n",
      " |  \n",
      " |  get_config(self)\n",
      " |      Returns the config of the layer.\n",
      " |      \n",
      " |      A layer config is a Python dictionary (serializable)\n",
      " |      containing the configuration of a layer.\n",
      " |      The same layer can be reinstantiated later\n",
      " |      (without its trained weights) from this configuration.\n",
      " |      \n",
      " |      The config of a layer does not include connectivity\n",
      " |      information, nor the layer class name. These are handled\n",
      " |      by `Network` (one layer of abstraction above).\n",
      " |      \n",
      " |      # Returns\n",
      " |          Python dictionary.\n",
      " |  \n",
      " |  get_layer(self, name=None, index=None)\n",
      " |      Retrieves a layer based on either its name (unique) or index.\n",
      " |      \n",
      " |      If `name` and `index` are both provided, `index` will take precedence.\n",
      " |      \n",
      " |      Indices are based on order of horizontal graph traversal (bottom-up).\n",
      " |      \n",
      " |      # Arguments\n",
      " |          name: String, name of layer.\n",
      " |          index: Integer, index of layer.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A layer instance.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: In case of invalid layer name or index.\n",
      " |  \n",
      " |  get_weights(self)\n",
      " |      Retrieves the weights of the model.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A flat list of Numpy arrays.\n",
      " |  \n",
      " |  load_weights(self, filepath, by_name=False, skip_mismatch=False, reshape=False)\n",
      " |      Loads all layer weights from a HDF5 save file.\n",
      " |      \n",
      " |      If `by_name` is False (default) weights are loaded\n",
      " |      based on the network's topology, meaning the architecture\n",
      " |      should be the same as when the weights were saved.\n",
      " |      Note that layers that don't have weights are not taken\n",
      " |      into account in the topological ordering, so adding or\n",
      " |      removing layers is fine as long as they don't have weights.\n",
      " |      \n",
      " |      If `by_name` is True, weights are loaded into layers\n",
      " |      only if they share the same name. This is useful\n",
      " |      for fine-tuning or transfer-learning models where\n",
      " |      some of the layers have changed.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          filepath: String, path to the weights file to load.\n",
      " |          by_name: Boolean, whether to load weights by name\n",
      " |              or by topological order.\n",
      " |          skip_mismatch: Boolean, whether to skip loading of layers\n",
      " |              where there is a mismatch in the number of weights,\n",
      " |              or a mismatch in the shape of the weight\n",
      " |              (only valid when `by_name`=True).\n",
      " |          reshape: Reshape weights to fit the layer when the correct number\n",
      " |              of weight arrays is present but their shape does not match.\n",
      " |      \n",
      " |      \n",
      " |      # Raises\n",
      " |          ImportError: If h5py is not available.\n",
      " |  \n",
      " |  reset_states(self)\n",
      " |  \n",
      " |  run_internal_graph(self, inputs, masks=None)\n",
      " |      Computes output tensors for new inputs.\n",
      " |      \n",
      " |      # Note:\n",
      " |          - Expects `inputs` to be a list (potentially with 1 element).\n",
      " |          - Can be run on non-Keras tensors.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          inputs: List of tensors\n",
      " |          masks: List of masks (tensors or None).\n",
      " |      \n",
      " |      # Returns\n",
      " |          Three lists: output_tensors, output_masks, output_shapes\n",
      " |  \n",
      " |  save(self, filepath, overwrite=True, include_optimizer=True)\n",
      " |      Saves the model to a single HDF5 file.\n",
      " |      \n",
      " |      The savefile includes:\n",
      " |          - The model architecture, allowing to re-instantiate the model.\n",
      " |          - The model weights.\n",
      " |          - The state of the optimizer, allowing to resume training\n",
      " |              exactly where you left off.\n",
      " |      \n",
      " |      This allows you to save the entirety of the state of a model\n",
      " |      in a single file.\n",
      " |      \n",
      " |      Saved models can be reinstantiated via `keras.models.load_model`.\n",
      " |      The model returned by `load_model`\n",
      " |      is a compiled model ready to be used (unless the saved model\n",
      " |      was never compiled in the first place).\n",
      " |      \n",
      " |      # Arguments\n",
      " |          filepath: String, path to the file to save the weights to.\n",
      " |          overwrite: Whether to silently overwrite any existing file at the\n",
      " |              target location, or provide the user with a manual prompt.\n",
      " |          include_optimizer: If True, save optimizer's state together.\n",
      " |      \n",
      " |      # Example\n",
      " |      \n",
      " |      ```python\n",
      " |      from keras.models import load_model\n",
      " |      \n",
      " |      model.save('my_model.h5')  # creates a HDF5 file 'my_model.h5'\n",
      " |      del model  # deletes the existing model\n",
      " |      \n",
      " |      # returns a compiled model\n",
      " |      # identical to the previous one\n",
      " |      model = load_model('my_model.h5')\n",
      " |      ```\n",
      " |  \n",
      " |  save_weights(self, filepath, overwrite=True)\n",
      " |      Dumps all layer weights to a HDF5 file.\n",
      " |      \n",
      " |      The weight file has:\n",
      " |          - `layer_names` (attribute), a list of strings\n",
      " |              (ordered names of model layers).\n",
      " |          - For every layer, a `group` named `layer.name`\n",
      " |              - For every such layer group, a group attribute `weight_names`,\n",
      " |                  a list of strings\n",
      " |                  (ordered names of weights tensor of the layer).\n",
      " |              - For every weight in the layer, a dataset\n",
      " |                  storing the weight value, named after the weight tensor.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          filepath: String, path to the file to save the weights to.\n",
      " |          overwrite: Whether to silently overwrite any existing file at the\n",
      " |              target location, or provide the user with a manual prompt.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ImportError: If h5py is not available.\n",
      " |  \n",
      " |  set_weights(self, weights)\n",
      " |      Sets the weights of the model.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          weights: A list of Numpy arrays with shapes and types matching\n",
      " |              the output of `model.get_weights()`.\n",
      " |  \n",
      " |  summary(self, line_length=None, positions=None, print_fn=None)\n",
      " |      Prints a string summary of the network.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          line_length: Total length of printed lines\n",
      " |              (e.g. set this to adapt the display to different\n",
      " |              terminal window sizes).\n",
      " |          positions: Relative or absolute positions of log elements\n",
      " |              in each line. If not provided,\n",
      " |              defaults to `[.33, .55, .67, 1.]`.\n",
      " |          print_fn: Print function to use.\n",
      " |              It will be called on each line of the summary.\n",
      " |              You can set it to a custom function\n",
      " |              in order to capture the string summary.\n",
      " |              It defaults to `print` (prints to stdout).\n",
      " |  \n",
      " |  to_json(self, **kwargs)\n",
      " |      Returns a JSON string containing the network configuration.\n",
      " |      \n",
      " |      To load a network from a JSON save file, use\n",
      " |      `keras.models.model_from_json(json_string, custom_objects={})`.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          **kwargs: Additional keyword arguments\n",
      " |              to be passed to `json.dumps()`.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A JSON string.\n",
      " |  \n",
      " |  to_yaml(self, **kwargs)\n",
      " |      Returns a yaml string containing the network configuration.\n",
      " |      \n",
      " |      To load a network from a yaml save file, use\n",
      " |      `keras.models.model_from_yaml(yaml_string, custom_objects={})`.\n",
      " |      \n",
      " |      `custom_objects` should be a dictionary mapping\n",
      " |      the names of custom losses / layers / etc to the corresponding\n",
      " |      functions / classes.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          **kwargs: Additional keyword arguments\n",
      " |              to be passed to `yaml.dump()`.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A YAML string.\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Class methods inherited from keras.engine.network.Network:\n",
      " |  \n",
      " |  from_config(config, custom_objects=None) from builtins.type\n",
      " |      Instantiates a Model from its config (output of `get_config()`).\n",
      " |      \n",
      " |      # Arguments\n",
      " |          config: Model config dictionary.\n",
      " |          custom_objects: Optional dictionary mapping names\n",
      " |              (strings) to custom classes or functions to be\n",
      " |              considered during deserialization.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A model instance.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: In case of improperly formatted config dict.\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data descriptors inherited from keras.engine.network.Network:\n",
      " |  \n",
      " |  input_spec\n",
      " |      Gets the model's input specs.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A list of `InputSpec` instances (one per input to the model)\n",
      " |              or a single instance if the model has only one input.\n",
      " |  \n",
      " |  layers\n",
      " |  \n",
      " |  losses\n",
      " |      Retrieves the model's losses.\n",
      " |      \n",
      " |      Will only include losses that are either\n",
      " |      unconditional, or conditional on inputs to this model\n",
      " |      (e.g. will not include losses that depend on tensors\n",
      " |      that aren't inputs to this model).\n",
      " |      \n",
      " |      # Returns\n",
      " |          A list of loss tensors.\n",
      " |  \n",
      " |  non_trainable_weights\n",
      " |  \n",
      " |  state_updates\n",
      " |      Returns the `updates` from all layers that are stateful.\n",
      " |      \n",
      " |      This is useful for separating training updates and\n",
      " |      state updates, e.g. when we need to update a layer's internal state\n",
      " |      during prediction.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A list of update ops.\n",
      " |  \n",
      " |  stateful\n",
      " |  \n",
      " |  trainable_weights\n",
      " |  \n",
      " |  updates\n",
      " |      Retrieves the model's updates.\n",
      " |      \n",
      " |      Will only include updates that are either\n",
      " |      unconditional, or conditional on inputs to this model\n",
      " |      (e.g. will not include updates that depend on tensors\n",
      " |      that aren't inputs to this model).\n",
      " |      \n",
      " |      # Returns\n",
      " |          A list of update ops.\n",
      " |  \n",
      " |  uses_learning_phase\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Methods inherited from keras.engine.base_layer.Layer:\n",
      " |  \n",
      " |  __call__(self, inputs, **kwargs)\n",
      " |      Wrapper around self.call(), for handling internal references.\n",
      " |      \n",
      " |      If a Keras tensor is passed:\n",
      " |          - We call self._add_inbound_node().\n",
      " |          - If necessary, we `build` the layer to match\n",
      " |              the _keras_shape of the input(s).\n",
      " |          - We update the _keras_shape of every input tensor with\n",
      " |              its new shape (obtained via self.compute_output_shape).\n",
      " |              This is done as part of _add_inbound_node().\n",
      " |          - We update the _keras_history of the output tensor(s)\n",
      " |              with the current layer.\n",
      " |              This is done as part of _add_inbound_node().\n",
      " |      \n",
      " |      # Arguments\n",
      " |          inputs: Can be a tensor or list/tuple of tensors.\n",
      " |          **kwargs: Additional keyword arguments to be passed to `call()`.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Output of the layer's `call` method.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: in case the layer is missing shape information\n",
      " |              for its `build` call.\n",
      " |  \n",
      " |  add_loss(self, losses, inputs=None)\n",
      " |      Adds losses to the layer.\n",
      " |      \n",
      " |      The loss may potentially be conditional on some inputs tensors,\n",
      " |      for instance activity losses are conditional on the layer's inputs.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          losses: loss tensor or list of loss tensors\n",
      " |              to add to the layer.\n",
      " |          inputs: input tensor or list of inputs tensors to mark\n",
      " |              the losses as conditional on these inputs.\n",
      " |              If None is passed, the loss is assumed unconditional\n",
      " |              (e.g. L2 weight regularization, which only depends\n",
      " |              on the layer's weights variables, not on any inputs tensors).\n",
      " |  \n",
      " |  add_update(self, updates, inputs=None)\n",
      " |      Adds updates to the layer.\n",
      " |      \n",
      " |      The updates may potentially be conditional on some inputs tensors,\n",
      " |      for instance batch norm updates are conditional on the layer's inputs.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          updates: update op or list of update ops\n",
      " |              to add to the layer.\n",
      " |          inputs: input tensor or list of inputs tensors to mark\n",
      " |              the updates as conditional on these inputs.\n",
      " |              If None is passed, the updates are assumed unconditional.\n",
      " |  \n",
      " |  add_weight(self, name, shape, dtype=None, initializer=None, regularizer=None, trainable=True, constraint=None)\n",
      " |      Adds a weight variable to the layer.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          name: String, the name for the weight variable.\n",
      " |          shape: The shape tuple of the weight.\n",
      " |          dtype: The dtype of the weight.\n",
      " |          initializer: An Initializer instance (callable).\n",
      " |          regularizer: An optional Regularizer instance.\n",
      " |          trainable: A boolean, whether the weight should\n",
      " |              be trained via backprop or not (assuming\n",
      " |              that the layer itself is also trainable).\n",
      " |          constraint: An optional Constraint instance.\n",
      " |      \n",
      " |      # Returns\n",
      " |          The created weight variable.\n",
      " |  \n",
      " |  assert_input_compatibility(self, inputs)\n",
      " |      Checks compatibility between the layer and provided inputs.\n",
      " |      \n",
      " |      This checks that the tensor(s) `input`\n",
      " |      verify the input assumptions of the layer\n",
      " |      (if any). If not, exceptions are raised.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          inputs: input tensor or list of input tensors.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: in case of mismatch between\n",
      " |              the provided inputs and the expectations of the layer.\n",
      " |  \n",
      " |  build(self, input_shape)\n",
      " |      Creates the layer weights.\n",
      " |      \n",
      " |      Must be implemented on all layers that have weights.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          input_shape: Keras tensor (future input to layer)\n",
      " |              or list/tuple of Keras tensors to reference\n",
      " |              for weight shape computations.\n",
      " |  \n",
      " |  count_params(self)\n",
      " |      Counts the total number of scalars composing the weights.\n",
      " |      \n",
      " |      # Returns\n",
      " |          An integer count.\n",
      " |      \n",
      " |      # Raises\n",
      " |          RuntimeError: if the layer isn't yet built\n",
      " |              (in which case its weights aren't yet defined).\n",
      " |  \n",
      " |  get_input_at(self, node_index)\n",
      " |      Retrieves the input tensor(s) of a layer at a given node.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          node_index: Integer, index of the node\n",
      " |              from which to retrieve the attribute.\n",
      " |              E.g. `node_index=0` will correspond to the\n",
      " |              first time the layer was called.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A tensor (or list of tensors if the layer has multiple inputs).\n",
      " |  \n",
      " |  get_input_mask_at(self, node_index)\n",
      " |      Retrieves the input mask tensor(s) of a layer at a given node.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          node_index: Integer, index of the node\n",
      " |              from which to retrieve the attribute.\n",
      " |              E.g. `node_index=0` will correspond to the\n",
      " |              first time the layer was called.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A mask tensor\n",
      " |          (or list of tensors if the layer has multiple inputs).\n",
      " |  \n",
      " |  get_input_shape_at(self, node_index)\n",
      " |      Retrieves the input shape(s) of a layer at a given node.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          node_index: Integer, index of the node\n",
      " |              from which to retrieve the attribute.\n",
      " |              E.g. `node_index=0` will correspond to the\n",
      " |              first time the layer was called.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A shape tuple\n",
      " |          (or list of shape tuples if the layer has multiple inputs).\n",
      " |  \n",
      " |  get_losses_for(self, inputs)\n",
      " |  \n",
      " |  get_output_at(self, node_index)\n",
      " |      Retrieves the output tensor(s) of a layer at a given node.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          node_index: Integer, index of the node\n",
      " |              from which to retrieve the attribute.\n",
      " |              E.g. `node_index=0` will correspond to the\n",
      " |              first time the layer was called.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A tensor (or list of tensors if the layer has multiple outputs).\n",
      " |  \n",
      " |  get_output_mask_at(self, node_index)\n",
      " |      Retrieves the output mask tensor(s) of a layer at a given node.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          node_index: Integer, index of the node\n",
      " |              from which to retrieve the attribute.\n",
      " |              E.g. `node_index=0` will correspond to the\n",
      " |              first time the layer was called.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A mask tensor\n",
      " |          (or list of tensors if the layer has multiple outputs).\n",
      " |  \n",
      " |  get_output_shape_at(self, node_index)\n",
      " |      Retrieves the output shape(s) of a layer at a given node.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          node_index: Integer, index of the node\n",
      " |              from which to retrieve the attribute.\n",
      " |              E.g. `node_index=0` will correspond to the\n",
      " |              first time the layer was called.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A shape tuple\n",
      " |          (or list of shape tuples if the layer has multiple outputs).\n",
      " |  \n",
      " |  get_updates_for(self, inputs)\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data descriptors inherited from keras.engine.base_layer.Layer:\n",
      " |  \n",
      " |  __dict__\n",
      " |      dictionary for instance variables (if defined)\n",
      " |  \n",
      " |  __weakref__\n",
      " |      list of weak references to the object (if defined)\n",
      " |  \n",
      " |  built\n",
      " |  \n",
      " |  input\n",
      " |      Retrieves the input tensor(s) of a layer.\n",
      " |      \n",
      " |      Only applicable if the layer has exactly one inbound node,\n",
      " |      i.e. if it is connected to one incoming layer.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Input tensor or list of input tensors.\n",
      " |      \n",
      " |      # Raises\n",
      " |          AttributeError: if the layer is connected to\n",
      " |          more than one incoming layers.\n",
      " |  \n",
      " |  input_mask\n",
      " |      Retrieves the input mask tensor(s) of a layer.\n",
      " |      \n",
      " |      Only applicable if the layer has exactly one inbound node,\n",
      " |      i.e. if it is connected to one incoming layer.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Input mask tensor (potentially None) or list of input\n",
      " |          mask tensors.\n",
      " |      \n",
      " |      # Raises\n",
      " |          AttributeError: if the layer is connected to\n",
      " |          more than one incoming layers.\n",
      " |  \n",
      " |  input_shape\n",
      " |      Retrieves the input shape tuple(s) of a layer.\n",
      " |      \n",
      " |      Only applicable if the layer has exactly one inbound node,\n",
      " |      i.e. if it is connected to one incoming layer.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Input shape tuple\n",
      " |          (or list of input shape tuples, one tuple per input tensor).\n",
      " |      \n",
      " |      # Raises\n",
      " |          AttributeError: if the layer is connected to\n",
      " |          more than one incoming layers.\n",
      " |  \n",
      " |  output\n",
      " |      Retrieves the output tensor(s) of a layer.\n",
      " |      \n",
      " |      Only applicable if the layer has exactly one inbound node,\n",
      " |      i.e. if it is connected to one incoming layer.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Output tensor or list of output tensors.\n",
      " |      \n",
      " |      # Raises\n",
      " |          AttributeError: if the layer is connected to\n",
      " |          more than one incoming layers.\n",
      " |  \n",
      " |  output_mask\n",
      " |      Retrieves the output mask tensor(s) of a layer.\n",
      " |      \n",
      " |      Only applicable if the layer has exactly one inbound node,\n",
      " |      i.e. if it is connected to one incoming layer.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Output mask tensor (potentially None) or list of output\n",
      " |          mask tensors.\n",
      " |      \n",
      " |      # Raises\n",
      " |          AttributeError: if the layer is connected to\n",
      " |          more than one incoming layers.\n",
      " |  \n",
      " |  output_shape\n",
      " |      Retrieves the output shape tuple(s) of a layer.\n",
      " |      \n",
      " |      Only applicable if the layer has one inbound node,\n",
      " |      or if all inbound nodes have the same output shape.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Output shape tuple\n",
      " |          (or list of input shape tuples, one tuple per output tensor).\n",
      " |      \n",
      " |      # Raises\n",
      " |          AttributeError: if the layer is connected to\n",
      " |          more than one incoming layers.\n",
      " |  \n",
      " |  weights\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\li_ni\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:40: UserWarning: Update your `Model` call to the Keras 2 API: `Model(inputs=Tensor(\"in..., outputs=Tensor(\"co...)`\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ISIC_0000034.jpg\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\li_ni\\Anaconda3\\lib\\site-packages\\keras_preprocessing\\image\\utils.py:98: UserWarning: grayscale is deprecated. Please use color_mode = \"grayscale\"\n",
      "  warnings.warn('grayscale is deprecated. Please use '\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ISIC_0000054.jpg\n",
      "ISIC_0000058.jpg\n",
      "ISIC_0000060.jpg\n",
      "ISIC_0000064.jpg\n",
      "ISIC_0000079.jpg\n",
      "ISIC_0000081.jpg\n",
      "ISIC_0000112.jpg\n",
      "ISIC_0000117.jpg\n",
      "ISIC_0000128.jpg\n",
      "ISIC_0000137.jpg\n",
      "ISIC_0000172.jpg\n",
      "ISIC_0000184.jpg\n",
      "ISIC_0000207.jpg\n",
      "ISIC_0000219.jpg\n",
      "ISIC_0000222.jpg\n",
      "ISIC_0000224.jpg\n",
      "ISIC_0000228.jpg\n",
      "ISIC_0000262.jpg\n",
      "ISIC_0000269.jpg\n",
      "ISIC_0000274.jpg\n",
      "ISIC_0000277.jpg\n",
      "ISIC_0000279.jpg\n",
      "ISIC_0000299.jpg\n",
      "ISIC_0000310.jpg\n",
      "ISIC_0000331.jpg\n",
      "ISIC_0000336.jpg\n",
      "ISIC_0000349.jpg\n",
      "ISIC_0000350.jpg\n",
      "ISIC_0000357.jpg\n",
      "ISIC_0000361.jpg\n",
      "ISIC_0000363.jpg\n",
      "ISIC_0000376.jpg\n",
      "ISIC_0000383.jpg\n",
      "ISIC_0000425.jpg\n",
      "ISIC_0000426.jpg\n",
      "ISIC_0000470.jpg\n",
      "ISIC_0000479.jpg\n",
      "ISIC_0000482.jpg\n",
      "ISIC_0000487.jpg\n",
      "ISIC_0000490.jpg\n",
      "ISIC_0000513.jpg\n",
      "ISIC_0000519.jpg\n",
      "ISIC_0000520.jpg\n",
      "ISIC_0000900.jpg\n",
      "ISIC_0001103.jpg\n",
      "ISIC_0001163.jpg\n",
      "ISIC_0001385.jpg\n",
      "ISIC_0002093.jpg\n",
      "ISIC_0002353.jpg\n",
      "ISIC_0002780.jpg\n",
      "ISIC_0002871.jpg\n",
      "ISIC_0003005.jpg\n",
      "ISIC_0006114.jpg\n",
      "ISIC_0006350.jpg\n",
      "ISIC_0006711.jpg\n",
      "ISIC_0006776.jpg\n",
      "ISIC_0007156.jpg\n",
      "ISIC_0007788.jpg\n",
      "ISIC_0007796.jpg\n",
      "ISIC_0008116.jpg\n",
      "ISIC_0008280.jpg\n",
      "ISIC_0008528.jpg\n",
      "ISIC_0008785.jpg\n",
      "ISIC_0008998.jpg\n",
      "ISIC_0009583.jpg\n",
      "ISIC_0009873.jpg\n",
      "ISIC_0009883.jpg\n",
      "ISIC_0009914.jpg\n",
      "ISIC_0009927.jpg\n",
      "ISIC_0009939.jpg\n",
      "ISIC_0009951.jpg\n",
      "ISIC_0009958.jpg\n",
      "ISIC_0009975.jpg\n",
      "ISIC_0009977.jpg\n",
      "ISIC_0009990.jpg\n",
      "ISIC_0009992.jpg\n",
      "ISIC_0010011.jpg\n",
      "ISIC_0010025.jpg\n",
      "ISIC_0010029.jpg\n",
      "ISIC_0010041.jpg\n",
      "ISIC_0010042.jpg\n",
      "ISIC_0010054.jpg\n",
      "ISIC_0010066.jpg\n",
      "ISIC_0010077.jpg\n",
      "ISIC_0010102.jpg\n",
      "ISIC_0010184.jpg\n",
      "ISIC_0010186.jpg\n",
      "ISIC_0010201.jpg\n",
      "ISIC_0010215.jpg\n",
      "ISIC_0010228.jpg\n",
      "ISIC_0010231.jpg\n",
      "ISIC_0010233.jpg\n",
      "ISIC_0010241.jpg\n",
      "ISIC_0010256.jpg\n",
      "ISIC_0010262.jpg\n",
      "ISIC_0010264.jpg\n",
      "ISIC_0010326.jpg\n",
      "ISIC_0010330.jpg\n",
      "ISIC_0010341.jpg\n",
      "ISIC_0010361.jpg\n",
      "ISIC_0010380.jpg\n",
      "ISIC_0010382.jpg\n",
      "ISIC_0010441.jpg\n",
      "ISIC_0010445.jpg\n",
      "ISIC_0010448.jpg\n",
      "ISIC_0010466.jpg\n",
      "ISIC_0010475.jpg\n",
      "ISIC_0010490.jpg\n",
      "ISIC_0010494.jpg\n",
      "ISIC_0010557.jpg\n",
      "ISIC_0010562.jpg\n",
      "ISIC_0010570.jpg\n",
      "ISIC_0010854.jpg\n",
      "ISIC_0011085.jpg\n",
      "ISIC_0011115.jpg\n",
      "ISIC_0011158.jpg\n",
      "ISIC_0011166.jpg\n",
      "ISIC_0011169.jpg\n",
      "ISIC_0011208.jpg\n",
      "ISIC_0011225.jpg\n",
      "ISIC_0011295.jpg\n",
      "ISIC_0011322.jpg\n",
      "ISIC_0011338.jpg\n",
      "ISIC_0011339.jpg\n",
      "ISIC_0011345.jpg\n",
      "ISIC_0011361.jpg\n",
      "ISIC_0011362.jpg\n",
      "ISIC_0012086.jpg\n",
      "ISIC_0012116.jpg\n",
      "ISIC_0012127.jpg\n",
      "ISIC_0012151.jpg\n",
      "ISIC_0012156.jpg\n",
      "ISIC_0012160.jpg\n",
      "ISIC_0012182.jpg\n",
      "ISIC_0012203.jpg\n",
      "ISIC_0012207.jpg\n",
      "ISIC_0012208.jpg\n",
      "ISIC_0012223.jpg\n",
      "ISIC_0012248.jpg\n",
      "ISIC_0012356.jpg\n",
      "ISIC_0012376.jpg\n",
      "ISIC_0012381.jpg\n",
      "ISIC_0012413.jpg\n",
      "ISIC_0012442.jpg\n",
      "ISIC_0012473.jpg\n",
      "ISIC_0012478.jpg\n",
      "ISIC_0012487.jpg\n",
      "ISIC_0012551.jpg\n",
      "ISIC_0012653.jpg\n",
      "ISIC_0012656.jpg\n",
      "ISIC_0012671.jpg\n",
      "ISIC_0012835.jpg\n",
      "ISIC_0012883.jpg\n",
      "ISIC_0012891.jpg\n",
      "ISIC_0012898.jpg\n",
      "ISIC_0012911.jpg\n",
      "ISIC_0012949.jpg\n",
      "ISIC_0012988.jpg\n",
      "ISIC_0013044.jpg\n",
      "ISIC_0013073.jpg\n",
      "ISIC_0013087.jpg\n",
      "ISIC_0013106.jpg\n",
      "ISIC_0013128.jpg\n",
      "ISIC_0013169.jpg\n",
      "ISIC_0013196.jpg\n",
      "ISIC_0013197.jpg\n",
      "ISIC_0013207.jpg\n",
      "ISIC_0013227.jpg\n",
      "ISIC_0013229.jpg\n",
      "ISIC_0013269.jpg\n",
      "ISIC_0013274.jpg\n",
      "ISIC_0013275.jpg\n",
      "ISIC_0013356.jpg\n",
      "ISIC_0013360.jpg\n",
      "ISIC_0013365.jpg\n",
      "ISIC_0013378.jpg\n",
      "ISIC_0013414.jpg\n",
      "ISIC_0013455.jpg\n",
      "ISIC_0013518.jpg\n",
      "ISIC_0013565.jpg\n",
      "ISIC_0013580.jpg\n",
      "ISIC_0013585.jpg\n",
      "ISIC_0013621.jpg\n",
      "ISIC_0013626.jpg\n",
      "ISIC_0013636.jpg\n",
      "ISIC_0013651.jpg\n",
      "ISIC_0013667.jpg\n",
      "ISIC_0013670.jpg\n",
      "ISIC_0013689.jpg\n",
      "ISIC_0013733.jpg\n",
      "ISIC_0013748.jpg\n",
      "ISIC_0013775.jpg\n",
      "ISIC_0013796.jpg\n",
      "ISIC_0013802.jpg\n",
      "ISIC_0013806.jpg\n",
      "ISIC_0013830.jpg\n",
      "ISIC_0013861.jpg\n",
      "ISIC_0013897.jpg\n",
      "ISIC_0013918.jpg\n",
      "ISIC_0013982.jpg\n",
      "ISIC_0014073.jpg\n",
      "ISIC_0014157.jpg\n",
      "ISIC_0014181.jpg\n",
      "ISIC_0014217.jpg\n",
      "ISIC_0014233.jpg\n",
      "ISIC_0014248.jpg\n",
      "ISIC_0014253.jpg\n",
      "ISIC_0014273.jpg\n",
      "ISIC_0014289.jpg\n",
      "ISIC_0014324.jpg\n",
      "ISIC_0014331.jpg\n",
      "ISIC_0014361.jpg\n",
      "ISIC_0014365.jpg\n",
      "ISIC_0014366.jpg\n",
      "ISIC_0014438.jpg\n",
      "ISIC_0014489.jpg\n",
      "ISIC_0014525.jpg\n",
      "ISIC_0014585.jpg\n",
      "ISIC_0014609.jpg\n",
      "ISIC_0014625.jpg\n",
      "ISIC_0014688.jpg\n",
      "ISIC_0014694.jpg\n",
      "ISIC_0014713.jpg\n",
      "ISIC_0014716.jpg\n",
      "ISIC_0014760.jpg\n",
      "ISIC_0014770.jpg\n",
      "ISIC_0014783.jpg\n",
      "ISIC_0014806.jpg\n",
      "ISIC_0014818.jpg\n",
      "ISIC_0014825.jpg\n",
      "ISIC_0014830.jpg\n",
      "ISIC_0014835.jpg\n",
      "ISIC_0014867.jpg\n",
      "ISIC_0014883.jpg\n",
      "ISIC_0014968.jpg\n",
      "ISIC_0014969.jpg\n",
      "ISIC_0015003.jpg\n",
      "ISIC_0015016.jpg\n",
      "ISIC_0015019.jpg\n",
      "ISIC_0015037.jpg\n",
      "ISIC_0015040.jpg\n",
      "ISIC_0015078.jpg\n",
      "ISIC_0015113.jpg\n",
      "ISIC_0015118.jpg\n",
      "ISIC_0015133.jpg\n",
      "ISIC_0015167.jpg\n",
      "ISIC_0015226.jpg\n",
      "ISIC_0015250.jpg\n",
      "ISIC_0015254.jpg\n",
      "ISIC_0015353.jpg\n",
      "ISIC_0015411.jpg\n",
      "ISIC_0015419.jpg\n",
      "ISIC_0015627.jpg\n",
      "ISIC_0015951.jpg\n",
      "ISIC_0015952.jpg\n",
      "ISIC_0016023.jpg\n",
      "ISIC_0016028.jpg\n",
      "ISIC_0016043.jpg\n",
      "ISIC_0016060.jpg\n"
     ]
    }
   ],
   "source": [
    "file_names = next(os.walk(test_data_dir))[2]\n",
    "\n",
    "model = UnetModel()\n",
    "model.load_weights(\"unet_lesion.hdf5\")\n",
    "\n",
    "\n",
    "for file in file_names:\n",
    "    print(file)\n",
    "    grey_img = load_img(os.path.join(test_data_dir,file), target_size=(img_rows, img_cols), grayscale=True)\n",
    "    img = img_to_array(grey_img)\n",
    "    mean = np.mean(img)  # mean for data centering\n",
    "    std = np.std(img)  # std for data normalization\n",
    "    img -= mean\n",
    "    img /= std\n",
    "    img = np.reshape(img,(1,)+img.shape)\n",
    "    results = model.predict(img)\n",
    "\n",
    "    result_img = array_to_img(results[0] * 255 )\n",
    "    #plt.imshow(result_img)\n",
    "    result_img.save(os.path.join(test_data_pred_dir, file.split('.')[0] + '_predict.jpg'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "__________________________________________________________________________________________________\n",
      "Layer (type)                    Output Shape         Param #     Connected to                     \n",
      "==================================================================================================\n",
      "input_15 (InputLayer)           (None, 1, 256, 256)  0                                            \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_189 (Conv2D)             (None, 32, 256, 256) 320         input_15[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_190 (Conv2D)             (None, 32, 256, 256) 9248        conv2d_189[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_48 (MaxPooling2D) (None, 32, 128, 128) 0           conv2d_190[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_191 (Conv2D)             (None, 64, 128, 128) 18496       max_pooling2d_48[0][0]           \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_192 (Conv2D)             (None, 64, 128, 128) 36928       conv2d_191[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_49 (MaxPooling2D) (None, 64, 64, 64)   0           conv2d_192[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_193 (Conv2D)             (None, 128, 64, 64)  73856       max_pooling2d_49[0][0]           \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_194 (Conv2D)             (None, 128, 64, 64)  147584      conv2d_193[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_50 (MaxPooling2D) (None, 128, 32, 32)  0           conv2d_194[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_195 (Conv2D)             (None, 256, 32, 32)  295168      max_pooling2d_50[0][0]           \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_196 (Conv2D)             (None, 256, 32, 32)  590080      conv2d_195[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_51 (MaxPooling2D) (None, 256, 16, 16)  0           conv2d_196[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_197 (Conv2D)             (None, 512, 16, 16)  1180160     max_pooling2d_51[0][0]           \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_198 (Conv2D)             (None, 512, 16, 16)  2359808     conv2d_197[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "up_sampling2d_36 (UpSampling2D) (None, 512, 32, 32)  0           conv2d_198[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "merge_36 (Merge)                (None, 768, 32, 32)  0           up_sampling2d_36[0][0]           \n",
      "                                                                 conv2d_196[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_199 (Conv2D)             (None, 256, 32, 32)  1769728     merge_36[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_200 (Conv2D)             (None, 256, 32, 32)  590080      conv2d_199[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "up_sampling2d_37 (UpSampling2D) (None, 256, 64, 64)  0           conv2d_200[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "merge_37 (Merge)                (None, 384, 64, 64)  0           up_sampling2d_37[0][0]           \n",
      "                                                                 conv2d_194[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_201 (Conv2D)             (None, 128, 64, 64)  442496      merge_37[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_202 (Conv2D)             (None, 128, 64, 64)  147584      conv2d_201[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "up_sampling2d_38 (UpSampling2D) (None, 128, 128, 128 0           conv2d_202[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "merge_38 (Merge)                (None, 192, 128, 128 0           up_sampling2d_38[0][0]           \n",
      "                                                                 conv2d_192[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_203 (Conv2D)             (None, 64, 128, 128) 110656      merge_38[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_204 (Conv2D)             (None, 64, 128, 128) 36928       conv2d_203[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "up_sampling2d_39 (UpSampling2D) (None, 64, 256, 256) 0           conv2d_204[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "merge_39 (Merge)                (None, 96, 256, 256) 0           up_sampling2d_39[0][0]           \n",
      "                                                                 conv2d_190[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_205 (Conv2D)             (None, 32, 256, 256) 27680       merge_39[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_206 (Conv2D)             (None, 32, 256, 256) 9248        conv2d_205[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_207 (Conv2D)             (None, 1, 256, 256)  33          conv2d_206[0][0]                 \n",
      "==================================================================================================\n",
      "Total params: 7,846,081\n",
      "Trainable params: 7,846,081\n",
      "Non-trainable params: 0\n",
      "__________________________________________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "file_names = next(os.walk(test_data_dir))[2]\n",
    "image = file_names[0]\n",
    "fig = plt.figure()\n",
    "\n",
    "a = fig.add_subplot(1, 4, 1)\n",
    "imgplot = plt.imshow(load_img(os.path.join(test_data_dir,image)), shape = (256,256))\n",
    "a.set_title('Image')\n",
    "a.set_axis_off()\n",
    "\n",
    "a = fig.add_subplot(1, 4, 2)\n",
    "imgplot = plt.imshow(load_img(os.path.join(test_data_mask_dir,image.split('.')[0]+\"_segmentation.png\")), shape = (256,256))\n",
    "a.set_title('Mask')\n",
    "a.set_axis_off()\n",
    "\n",
    "a = fig.add_subplot(1, 4, 3)\n",
    "imgplot = plt.imshow(load_img(os.path.join(test_data_pred_dir,image.split('.')[0]+\"_predict.jpg\")), shape = (256,256))\n",
    "a.set_title('Prediction')\n",
    "a.set_axis_off()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "african_e66lephant_output = model.output[:, 386]                          \n",
    "\n",
    "last_conv_layer = model.get_layer('block5_conv3')                         \n",
    "\n",
    "grads = K.gradients(african_elephant_output, last_conv_layer.output)[0]   \n",
    "\n",
    "pooled_grads = K.mean(grads, axis=(0, 1, 2))                              \n",
    "\n",
    "iterate = K.function([model.input],\n",
    "                     [pooled_grads, last_conv_layer.output[0]])           \n",
    "\n",
    "pooled_grads_value, conv_layer_output_value = iterate([x])                \n",
    "\n",
    "for i in range(512):                                                      \n",
    "    conv_layer_output_value[:, :, i] *= pooled_grads_value[i]             \n",
    "\n",
    "heatmap = np.mean(conv_layer_output_value, axis=-1)                       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 135,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor 'conv2d_207/Sigmoid:0' shape=(?, 1, 256, 256) dtype=float32>"
      ]
     },
     "execution_count": 135,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 136,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on Model in module keras.engine.training object:\n",
      "\n",
      "class Model(keras.engine.topology.Container)\n",
      " |  The `Model` class adds training & evaluation routines to a `Container`.\n",
      " |  \n",
      " |  Method resolution order:\n",
      " |      Model\n",
      " |      keras.engine.topology.Container\n",
      " |      keras.engine.topology.Layer\n",
      " |      builtins.object\n",
      " |  \n",
      " |  Methods defined here:\n",
      " |  \n",
      " |  compile(self, optimizer, loss=None, metrics=None, loss_weights=None, sample_weight_mode=None, weighted_metrics=None, target_tensors=None, **kwargs)\n",
      " |      Configures the model for training.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          optimizer: String (name of optimizer) or optimizer instance.\n",
      " |              See [optimizers](/optimizers).\n",
      " |          loss: String (name of objective function) or objective function.\n",
      " |              See [losses](/losses).\n",
      " |              If the model has multiple outputs, you can use a different loss\n",
      " |              on each output by passing a dictionary or a list of losses.\n",
      " |              The loss value that will be minimized by the model\n",
      " |              will then be the sum of all individual losses.\n",
      " |          metrics: List of metrics to be evaluated by the model\n",
      " |              during training and testing.\n",
      " |              Typically you will use `metrics=['accuracy']`.\n",
      " |              To specify different metrics for different outputs of a\n",
      " |              multi-output model, you could also pass a dictionary,\n",
      " |              such as `metrics={'output_a': 'accuracy'}`.\n",
      " |          loss_weights: Optional list or dictionary specifying scalar\n",
      " |              coefficients (Python floats) to weight the loss contributions\n",
      " |              of different model outputs.\n",
      " |              The loss value that will be minimized by the model\n",
      " |              will then be the *weighted sum* of all individual losses,\n",
      " |              weighted by the `loss_weights` coefficients.\n",
      " |              If a list, it is expected to have a 1:1 mapping\n",
      " |              to the model's outputs. If a tensor, it is expected to map\n",
      " |              output names (strings) to scalar coefficients.\n",
      " |          sample_weight_mode: If you need to do timestep-wise\n",
      " |              sample weighting (2D weights), set this to `\"temporal\"`.\n",
      " |              `None` defaults to sample-wise weights (1D).\n",
      " |              If the model has multiple outputs, you can use a different\n",
      " |              `sample_weight_mode` on each output by passing a\n",
      " |              dictionary or a list of modes.\n",
      " |          weighted_metrics: List of metrics to be evaluated and weighted\n",
      " |              by sample_weight or class_weight during training and testing.\n",
      " |          target_tensors: By default, Keras will create placeholders for the\n",
      " |              model's target, which will be fed with the target data during\n",
      " |              training. If instead you would like to use your own\n",
      " |              target tensors (in turn, Keras will not expect external\n",
      " |              Numpy data for these targets at training time), you\n",
      " |              can specify them via the `target_tensors` argument. It can be\n",
      " |              a single tensor (for a single-output model), a list of tensors,\n",
      " |              or a dict mapping output names to target tensors.\n",
      " |          **kwargs: When using the Theano/CNTK backends, these arguments\n",
      " |              are passed into `K.function`.\n",
      " |              When using the TensorFlow backend,\n",
      " |              these arguments are passed into `tf.Session.run`.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: In case of invalid arguments for\n",
      " |              `optimizer`, `loss`, `metrics` or `sample_weight_mode`.\n",
      " |  \n",
      " |  evaluate(self, x=None, y=None, batch_size=None, verbose=1, sample_weight=None, steps=None)\n",
      " |      Returns the loss value & metrics values for the model in test mode.\n",
      " |      \n",
      " |      Computation is done in batches.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          x: Numpy array of test data (if the model has a single input),\n",
      " |              or list of Numpy arrays (if the model has multiple inputs).\n",
      " |              If input layers in the model are named, you can also pass a\n",
      " |              dictionary mapping input names to Numpy arrays.\n",
      " |              `x` can be `None` (default) if feeding from\n",
      " |              framework-native tensors (e.g. TensorFlow data tensors).\n",
      " |          y: Numpy array of target (label) data\n",
      " |              (if the model has a single output),\n",
      " |              or list of Numpy arrays (if the model has multiple outputs).\n",
      " |              If output layers in the model are named, you can also pass a\n",
      " |              dictionary mapping output names to Numpy arrays.\n",
      " |              `y` can be `None` (default) if feeding from\n",
      " |              framework-native tensors (e.g. TensorFlow data tensors).\n",
      " |          batch_size: Integer or `None`.\n",
      " |              Number of samples per evaluation step.\n",
      " |              If unspecified, `batch_size` will default to 32.\n",
      " |          verbose: 0 or 1. Verbosity mode.\n",
      " |              0 = silent, 1 = progress bar.\n",
      " |          sample_weight: Optional Numpy array of weights for\n",
      " |              the test samples, used for weighting the loss function.\n",
      " |              You can either pass a flat (1D)\n",
      " |              Numpy array with the same length as the input samples\n",
      " |              (1:1 mapping between weights and samples),\n",
      " |              or in the case of temporal data,\n",
      " |              you can pass a 2D array with shape\n",
      " |              `(samples, sequence_length)`,\n",
      " |              to apply a different weight to every timestep of every sample.\n",
      " |              In this case you should make sure to specify\n",
      " |              `sample_weight_mode=\"temporal\"` in `compile()`.\n",
      " |          steps: Integer or `None`.\n",
      " |              Total number of steps (batches of samples)\n",
      " |              before declaring the evaluation round finished.\n",
      " |              Ignored with the default value of `None`.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Scalar test loss (if the model has a single output and no metrics)\n",
      " |          or list of scalars (if the model has multiple outputs\n",
      " |          and/or metrics). The attribute `model.metrics_names` will give you\n",
      " |          the display labels for the scalar outputs.\n",
      " |  \n",
      " |  evaluate_generator(self, generator, steps=None, max_queue_size=10, workers=1, use_multiprocessing=False)\n",
      " |      Evaluates the model on a data generator.\n",
      " |      \n",
      " |      The generator should return the same kind of data\n",
      " |      as accepted by `test_on_batch`.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          generator: Generator yielding tuples (inputs, targets)\n",
      " |              or (inputs, targets, sample_weights)\n",
      " |              or an instance of Sequence (keras.utils.Sequence)\n",
      " |              object in order to avoid duplicate data\n",
      " |              when using multiprocessing.\n",
      " |          steps: Total number of steps (batches of samples)\n",
      " |              to yield from `generator` before stopping.\n",
      " |              Optional for `Sequence`: if unspecified, will use\n",
      " |              the `len(generator)` as a number of steps.\n",
      " |          max_queue_size: maximum size for the generator queue\n",
      " |          workers: Integer. Maximum number of processes to spin up\n",
      " |              when using process based threading.\n",
      " |              If unspecified, `workers` will default to 1. If 0, will\n",
      " |              execute the generator on the main thread.\n",
      " |          use_multiprocessing: if True, use process based threading.\n",
      " |              Note that because\n",
      " |              this implementation relies on multiprocessing,\n",
      " |              you should not pass\n",
      " |              non picklable arguments to the generator\n",
      " |              as they can't be passed\n",
      " |              easily to children processes.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Scalar test loss (if the model has a single output and no metrics)\n",
      " |          or list of scalars (if the model has multiple outputs\n",
      " |          and/or metrics). The attribute `model.metrics_names` will give you\n",
      " |          the display labels for the scalar outputs.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: In case the generator yields\n",
      " |              data in an invalid format.\n",
      " |  \n",
      " |  fit(self, x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None, **kwargs)\n",
      " |      Trains the model for a fixed number of epochs (iterations on a dataset).\n",
      " |      \n",
      " |      # Arguments\n",
      " |          x: Numpy array of training data (if the model has a single input),\n",
      " |              or list of Numpy arrays (if the model has multiple inputs).\n",
      " |              If input layers in the model are named, you can also pass a\n",
      " |              dictionary mapping input names to Numpy arrays.\n",
      " |              `x` can be `None` (default) if feeding from\n",
      " |              framework-native tensors (e.g. TensorFlow data tensors).\n",
      " |          y: Numpy array of target (label) data\n",
      " |              (if the model has a single output),\n",
      " |              or list of Numpy arrays (if the model has multiple outputs).\n",
      " |              If output layers in the model are named, you can also pass a\n",
      " |              dictionary mapping output names to Numpy arrays.\n",
      " |              `y` can be `None` (default) if feeding from\n",
      " |              framework-native tensors (e.g. TensorFlow data tensors).\n",
      " |          batch_size: Integer or `None`.\n",
      " |              Number of samples per gradient update.\n",
      " |              If unspecified, `batch_size` will default to 32.\n",
      " |          epochs: Integer. Number of epochs to train the model.\n",
      " |              An epoch is an iteration over the entire `x` and `y`\n",
      " |              data provided.\n",
      " |              Note that in conjunction with `initial_epoch`,\n",
      " |              `epochs` is to be understood as \"final epoch\".\n",
      " |              The model is not trained for a number of iterations\n",
      " |              given by `epochs`, but merely until the epoch\n",
      " |              of index `epochs` is reached.\n",
      " |          verbose: Integer. 0, 1, or 2. Verbosity mode.\n",
      " |              0 = silent, 1 = progress bar, 2 = one line per epoch.\n",
      " |          callbacks: List of `keras.callbacks.Callback` instances.\n",
      " |              List of callbacks to apply during training.\n",
      " |              See [callbacks](/callbacks).\n",
      " |          validation_split: Float between 0 and 1.\n",
      " |              Fraction of the training data to be used as validation data.\n",
      " |              The model will set apart this fraction of the training data,\n",
      " |              will not train on it, and will evaluate\n",
      " |              the loss and any model metrics\n",
      " |              on this data at the end of each epoch.\n",
      " |              The validation data is selected from the last samples\n",
      " |              in the `x` and `y` data provided, before shuffling.\n",
      " |          validation_data: tuple `(x_val, y_val)` or tuple\n",
      " |              `(x_val, y_val, val_sample_weights)` on which to evaluate\n",
      " |              the loss and any model metrics at the end of each epoch.\n",
      " |              The model will not be trained on this data.\n",
      " |              `validation_data` will override `validation_split`.\n",
      " |          shuffle: Boolean (whether to shuffle the training data\n",
      " |              before each epoch) or str (for 'batch').\n",
      " |              'batch' is a special option for dealing with the\n",
      " |              limitations of HDF5 data; it shuffles in batch-sized chunks.\n",
      " |              Has no effect when `steps_per_epoch` is not `None`.\n",
      " |          class_weight: Optional dictionary mapping class indices (integers)\n",
      " |              to a weight (float) value, used for weighting the loss function\n",
      " |              (during training only).\n",
      " |              This can be useful to tell the model to\n",
      " |              \"pay more attention\" to samples from\n",
      " |              an under-represented class.\n",
      " |          sample_weight: Optional Numpy array of weights for\n",
      " |              the training samples, used for weighting the loss function\n",
      " |              (during training only). You can either pass a flat (1D)\n",
      " |              Numpy array with the same length as the input samples\n",
      " |              (1:1 mapping between weights and samples),\n",
      " |              or in the case of temporal data,\n",
      " |              you can pass a 2D array with shape\n",
      " |              `(samples, sequence_length)`,\n",
      " |              to apply a different weight to every timestep of every sample.\n",
      " |              In this case you should make sure to specify\n",
      " |              `sample_weight_mode=\"temporal\"` in `compile()`.\n",
      " |          initial_epoch: Integer.\n",
      " |              Epoch at which to start training\n",
      " |              (useful for resuming a previous training run).\n",
      " |          steps_per_epoch: Integer or `None`.\n",
      " |              Total number of steps (batches of samples)\n",
      " |              before declaring one epoch finished and starting the\n",
      " |              next epoch. When training with input tensors such as\n",
      " |              TensorFlow data tensors, the default `None` is equal to\n",
      " |              the number of samples in your dataset divided by\n",
      " |              the batch size, or 1 if that cannot be determined.\n",
      " |          validation_steps: Only relevant if `steps_per_epoch`\n",
      " |              is specified. Total number of steps (batches of samples)\n",
      " |              to validate before stopping.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A `History` object. Its `History.history` attribute is\n",
      " |          a record of training loss values and metrics values\n",
      " |          at successive epochs, as well as validation loss values\n",
      " |          and validation metrics values (if applicable).\n",
      " |      \n",
      " |      # Raises\n",
      " |          RuntimeError: If the model was never compiled.\n",
      " |          ValueError: In case of mismatch between the provided input data\n",
      " |              and what the model expects.\n",
      " |  \n",
      " |  fit_generator(self, generator, steps_per_epoch=None, epochs=1, verbose=1, callbacks=None, validation_data=None, validation_steps=None, class_weight=None, max_queue_size=10, workers=1, use_multiprocessing=False, shuffle=True, initial_epoch=0)\n",
      " |      Trains the model on data generated batch-by-batch by a Python generator or an instance of `Sequence`.\n",
      " |      \n",
      " |      The generator is run in parallel to the model, for efficiency.\n",
      " |      For instance, this allows you to do real-time data augmentation\n",
      " |      on images on CPU in parallel to training your model on GPU.\n",
      " |      \n",
      " |      The use of `keras.utils.Sequence` guarantees the ordering\n",
      " |      and guarantees the single use of every input per epoch when\n",
      " |      using `use_multiprocessing=True`.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          generator: A generator or an instance of `Sequence`\n",
      " |              (`keras.utils.Sequence`) object in order to avoid\n",
      " |              duplicate data when using multiprocessing.\n",
      " |              The output of the generator must be either\n",
      " |              - a tuple `(inputs, targets)`\n",
      " |              - a tuple `(inputs, targets, sample_weights)`.\n",
      " |              This tuple (a single output of the generator) makes a single\n",
      " |              batch. Therefore, all arrays in this tuple must have the same\n",
      " |              length (equal to the size of this batch). Different batches may\n",
      " |              have different sizes. For example, the last batch of the epoch\n",
      " |              is commonly smaller than the others, if the size of the dataset\n",
      " |              is not divisible by the batch size.\n",
      " |              The generator is expected to loop over its data\n",
      " |              indefinitely. An epoch finishes when `steps_per_epoch`\n",
      " |              batches have been seen by the model.\n",
      " |          steps_per_epoch: Integer.\n",
      " |              Total number of steps (batches of samples)\n",
      " |              to yield from `generator` before declaring one epoch\n",
      " |              finished and starting the next epoch. It should typically\n",
      " |              be equal to the number of samples of your dataset\n",
      " |              divided by the batch size.\n",
      " |              Optional for `Sequence`: if unspecified, will use\n",
      " |              the `len(generator)` as a number of steps.\n",
      " |          epochs: Integer. Number of epochs to train the model.\n",
      " |              An epoch is an iteration over the entire data provided,\n",
      " |              as defined by `steps_per_epoch`.\n",
      " |              Note that in conjunction with `initial_epoch`,\n",
      " |              `epochs` is to be understood as \"final epoch\".\n",
      " |              The model is not trained for a number of iterations\n",
      " |              given by `epochs`, but merely until the epoch\n",
      " |              of index `epochs` is reached.\n",
      " |          verbose: Integer. 0, 1, or 2. Verbosity mode.\n",
      " |              0 = silent, 1 = progress bar, 2 = one line per epoch.\n",
      " |          callbacks: List of `keras.callbacks.Callback` instances.\n",
      " |              List of callbacks to apply during training.\n",
      " |              See [callbacks](/callbacks).\n",
      " |          validation_data: This can be either\n",
      " |              - a generator for the validation data\n",
      " |              - tuple `(x_val, y_val)`\n",
      " |              - tuple `(x_val, y_val, val_sample_weights)`\n",
      " |              on which to evaluate\n",
      " |              the loss and any model metrics at the end of each epoch.\n",
      " |              The model will not be trained on this data.\n",
      " |          validation_steps: Only relevant if `validation_data`\n",
      " |              is a generator. Total number of steps (batches of samples)\n",
      " |              to yield from `validation_data` generator before stopping\n",
      " |              at the end of every epoch. It should typically\n",
      " |              be equal to the number of samples of your\n",
      " |              validation dataset divided by the batch size.\n",
      " |              Optional for `Sequence`: if unspecified, will use\n",
      " |              the `len(validation_data)` as a number of steps.\n",
      " |          class_weight: Optional dictionary mapping class indices (integers)\n",
      " |              to a weight (float) value, used for weighting the loss function\n",
      " |              (during training only). This can be useful to tell the model to\n",
      " |              \"pay more attention\" to samples from an under-represented class.\n",
      " |          max_queue_size: Integer. Maximum size for the generator queue.\n",
      " |              If unspecified, `max_queue_size` will default to 10.\n",
      " |          workers: Integer. Maximum number of processes to spin up\n",
      " |              when using process-based threading.\n",
      " |              If unspecified, `workers` will default to 1. If 0, will\n",
      " |              execute the generator on the main thread.\n",
      " |          use_multiprocessing: Boolean.\n",
      " |              If `True`, use process-based threading.\n",
      " |              If unspecified, `use_multiprocessing` will default to `False`.\n",
      " |              Note that because this implementation relies on multiprocessing,\n",
      " |              you should not pass non-picklable arguments to the generator\n",
      " |              as they can't be passed easily to children processes.\n",
      " |          shuffle: Boolean. Whether to shuffle the order of the batches at\n",
      " |              the beginning of each epoch. Only used with instances\n",
      " |              of `Sequence` (`keras.utils.Sequence`).\n",
      " |              Has no effect when `steps_per_epoch` is not `None`.\n",
      " |          initial_epoch: Integer.\n",
      " |              Epoch at which to start training\n",
      " |              (useful for resuming a previous training run).\n",
      " |      \n",
      " |      # Returns\n",
      " |          A `History` object. Its `History.history` attribute is\n",
      " |          a record of training loss values and metrics values\n",
      " |          at successive epochs, as well as validation loss values\n",
      " |          and validation metrics values (if applicable).\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: In case the generator yields data in an invalid format.\n",
      " |      \n",
      " |      # Example\n",
      " |      \n",
      " |      ```python\n",
      " |          def generate_arrays_from_file(path):\n",
      " |              while True:\n",
      " |                  with open(path) as f:\n",
      " |                      for line in f:\n",
      " |                          # create numpy arrays of input data\n",
      " |                          # and labels, from each line in the file\n",
      " |                          x1, x2, y = process_line(line)\n",
      " |                          yield ({'input_1': x1, 'input_2': x2}, {'output': y})\n",
      " |      \n",
      " |          model.fit_generator(generate_arrays_from_file('/my_file.txt'),\n",
      " |                              steps_per_epoch=10000, epochs=10)\n",
      " |      ```\n",
      " |  \n",
      " |  predict(self, x, batch_size=None, verbose=0, steps=None)\n",
      " |      Generates output predictions for the input samples.\n",
      " |      \n",
      " |      Computation is done in batches.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          x: The input data, as a Numpy array\n",
      " |              (or list of Numpy arrays if the model has multiple outputs).\n",
      " |          batch_size: Integer. If unspecified, it will default to 32.\n",
      " |          verbose: Verbosity mode, 0 or 1.\n",
      " |          steps: Total number of steps (batches of samples)\n",
      " |              before declaring the prediction round finished.\n",
      " |              Ignored with the default value of `None`.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Numpy array(s) of predictions.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: In case of mismatch between the provided\n",
      " |              input data and the model's expectations,\n",
      " |              or in case a stateful model receives a number of samples\n",
      " |              that is not a multiple of the batch size.\n",
      " |  \n",
      " |  predict_generator(self, generator, steps=None, max_queue_size=10, workers=1, use_multiprocessing=False, verbose=0)\n",
      " |      Generates predictions for the input samples from a data generator.\n",
      " |      \n",
      " |      The generator should return the same kind of data as accepted by\n",
      " |      `predict_on_batch`.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          generator: Generator yielding batches of input samples\n",
      " |              or an instance of Sequence (keras.utils.Sequence)\n",
      " |              object in order to avoid duplicate data\n",
      " |              when using multiprocessing.\n",
      " |          steps: Total number of steps (batches of samples)\n",
      " |              to yield from `generator` before stopping.\n",
      " |              Optional for `Sequence`: if unspecified, will use\n",
      " |              the `len(generator)` as a number of steps.\n",
      " |          max_queue_size: Maximum size for the generator queue.\n",
      " |          workers: Integer. Maximum number of processes to spin up\n",
      " |              when using process based threading.\n",
      " |              If unspecified, `workers` will default to 1. If 0, will\n",
      " |              execute the generator on the main thread.\n",
      " |          use_multiprocessing: If `True`, use process based threading.\n",
      " |              Note that because\n",
      " |              this implementation relies on multiprocessing,\n",
      " |              you should not pass\n",
      " |              non picklable arguments to the generator\n",
      " |              as they can't be passed\n",
      " |              easily to children processes.\n",
      " |          verbose: verbosity mode, 0 or 1.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Numpy array(s) of predictions.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: In case the generator yields\n",
      " |              data in an invalid format.\n",
      " |  \n",
      " |  predict_on_batch(self, x)\n",
      " |      Returns predictions for a single batch of samples.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          x: Input samples, as a Numpy array.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Numpy array(s) of predictions.\n",
      " |  \n",
      " |  test_on_batch(self, x, y, sample_weight=None)\n",
      " |      Test the model on a single batch of samples.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          x: Numpy array of test data,\n",
      " |              or list of Numpy arrays if the model has multiple inputs.\n",
      " |              If all inputs in the model are named,\n",
      " |              you can also pass a dictionary\n",
      " |              mapping input names to Numpy arrays.\n",
      " |          y: Numpy array of target data,\n",
      " |              or list of Numpy arrays if the model has multiple outputs.\n",
      " |              If all outputs in the model are named,\n",
      " |              you can also pass a dictionary\n",
      " |              mapping output names to Numpy arrays.\n",
      " |          sample_weight: Optional array of the same length as x, containing\n",
      " |              weights to apply to the model's loss for each sample.\n",
      " |              In the case of temporal data, you can pass a 2D array\n",
      " |              with shape (samples, sequence_length),\n",
      " |              to apply a different weight to every timestep of every sample.\n",
      " |              In this case you should make sure to specify\n",
      " |              sample_weight_mode=\"temporal\" in compile().\n",
      " |      \n",
      " |      # Returns\n",
      " |          Scalar test loss (if the model has a single output and no metrics)\n",
      " |          or list of scalars (if the model has multiple outputs\n",
      " |          and/or metrics). The attribute `model.metrics_names` will give you\n",
      " |          the display labels for the scalar outputs.\n",
      " |  \n",
      " |  train_on_batch(self, x, y, sample_weight=None, class_weight=None)\n",
      " |      Runs a single gradient update on a single batch of data.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          x: Numpy array of training data,\n",
      " |              or list of Numpy arrays if the model has multiple inputs.\n",
      " |              If all inputs in the model are named,\n",
      " |              you can also pass a dictionary\n",
      " |              mapping input names to Numpy arrays.\n",
      " |          y: Numpy array of target data,\n",
      " |              or list of Numpy arrays if the model has multiple outputs.\n",
      " |              If all outputs in the model are named,\n",
      " |              you can also pass a dictionary\n",
      " |              mapping output names to Numpy arrays.\n",
      " |          sample_weight: Optional array of the same length as x, containing\n",
      " |              weights to apply to the model's loss for each sample.\n",
      " |              In the case of temporal data, you can pass a 2D array\n",
      " |              with shape (samples, sequence_length),\n",
      " |              to apply a different weight to every timestep of every sample.\n",
      " |              In this case you should make sure to specify\n",
      " |              sample_weight_mode=\"temporal\" in compile().\n",
      " |          class_weight: Optional dictionary mapping\n",
      " |              class indices (integers) to\n",
      " |              a weight (float) to apply to the model's loss for the samples\n",
      " |              from this class during training.\n",
      " |              This can be useful to tell the model to \"pay more attention\" to\n",
      " |              samples from an under-represented class.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Scalar training loss\n",
      " |          (if the model has a single output and no metrics)\n",
      " |          or list of scalars (if the model has multiple outputs\n",
      " |          and/or metrics). The attribute `model.metrics_names` will give you\n",
      " |          the display labels for the scalar outputs.\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Methods inherited from keras.engine.topology.Container:\n",
      " |  \n",
      " |  __init__(self, inputs, outputs, name=None)\n",
      " |      Initialize self.  See help(type(self)) for accurate signature.\n",
      " |  \n",
      " |  call(self, inputs, mask=None)\n",
      " |      Calls the model on new inputs.\n",
      " |      \n",
      " |      In this case `call` just reapplies\n",
      " |      all ops in the graph to the new inputs\n",
      " |      (e.g. build a new computational graph from the provided inputs).\n",
      " |      \n",
      " |      A model is callable on non-Keras tensors.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          inputs: A tensor or list of tensors.\n",
      " |          mask: A mask or list of masks. A mask can be\n",
      " |              either a tensor or None (no mask).\n",
      " |      \n",
      " |      # Returns\n",
      " |          A tensor if there is a single output, or\n",
      " |          a list of tensors if there are more than one outputs.\n",
      " |  \n",
      " |  compute_mask(self, inputs, mask)\n",
      " |      Computes an output mask tensor.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          inputs: Tensor or list of tensors.\n",
      " |          mask: Tensor or list of tensors.\n",
      " |      \n",
      " |      # Returns\n",
      " |          None or a tensor (or list of tensors,\n",
      " |              one per output tensor of the layer).\n",
      " |  \n",
      " |  compute_output_shape(self, input_shape)\n",
      " |      Computes the output shape of the layer.\n",
      " |      \n",
      " |      Assumes that the layer will be built\n",
      " |      to match that input shape provided.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          input_shape: Shape tuple (tuple of integers)\n",
      " |              or list of shape tuples (one per output tensor of the layer).\n",
      " |              Shape tuples can include None for free dimensions,\n",
      " |              instead of an integer.\n",
      " |      \n",
      " |      # Returns\n",
      " |          An input shape tuple.\n",
      " |  \n",
      " |  get_config(self)\n",
      " |      Returns the config of the layer.\n",
      " |      \n",
      " |      A layer config is a Python dictionary (serializable)\n",
      " |      containing the configuration of a layer.\n",
      " |      The same layer can be reinstantiated later\n",
      " |      (without its trained weights) from this configuration.\n",
      " |      \n",
      " |      The config of a layer does not include connectivity\n",
      " |      information, nor the layer class name. These are handled\n",
      " |      by `Container` (one layer of abstraction above).\n",
      " |      \n",
      " |      # Returns\n",
      " |          Python dictionary.\n",
      " |  \n",
      " |  get_layer(self, name=None, index=None)\n",
      " |      Retrieves a layer based on either its name (unique) or index.\n",
      " |      \n",
      " |      If `name` and `index` are both provided, `index` will take precedence.\n",
      " |      \n",
      " |      Indices are based on order of horizontal graph traversal (bottom-up).\n",
      " |      \n",
      " |      # Arguments\n",
      " |          name: String, name of layer.\n",
      " |          index: Integer, index of layer.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A layer instance.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: In case of invalid layer name or index.\n",
      " |  \n",
      " |  get_weights(self)\n",
      " |      Retrieves the weights of the model.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A flat list of Numpy arrays.\n",
      " |  \n",
      " |  load_weights(self, filepath, by_name=False, skip_mismatch=False, reshape=False)\n",
      " |      Loads all layer weights from a HDF5 save file.\n",
      " |      \n",
      " |      If `by_name` is False (default) weights are loaded\n",
      " |      based on the network's topology, meaning the architecture\n",
      " |      should be the same as when the weights were saved.\n",
      " |      Note that layers that don't have weights are not taken\n",
      " |      into account in the topological ordering, so adding or\n",
      " |      removing layers is fine as long as they don't have weights.\n",
      " |      \n",
      " |      If `by_name` is True, weights are loaded into layers\n",
      " |      only if they share the same name. This is useful\n",
      " |      for fine-tuning or transfer-learning models where\n",
      " |      some of the layers have changed.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          filepath: String, path to the weights file to load.\n",
      " |          by_name: Boolean, whether to load weights by name\n",
      " |              or by topological order.\n",
      " |          skip_mismatch: Boolean, whether to skip loading of layers\n",
      " |              where there is a mismatch in the number of weights,\n",
      " |              or a mismatch in the shape of the weight\n",
      " |              (only valid when `by_name`=True).\n",
      " |          reshape: Reshape weights to fit the layer when the correct number\n",
      " |              of weight arrays is present but their shape does not match.\n",
      " |      \n",
      " |      \n",
      " |      # Raises\n",
      " |          ImportError: If h5py is not available.\n",
      " |  \n",
      " |  reset_states(self)\n",
      " |  \n",
      " |  run_internal_graph(self, inputs, masks=None)\n",
      " |      Computes output tensors for new inputs.\n",
      " |      \n",
      " |      # Note:\n",
      " |          - Expects `inputs` to be a list (potentially with 1 element).\n",
      " |          - Can be run on non-Keras tensors.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          inputs: List of tensors\n",
      " |          masks: List of masks (tensors or None).\n",
      " |      \n",
      " |      # Returns\n",
      " |          Three lists: output_tensors, output_masks, output_shapes\n",
      " |  \n",
      " |  save(self, filepath, overwrite=True, include_optimizer=True)\n",
      " |      Saves the model to a single HDF5 file.\n",
      " |      \n",
      " |      The savefile includes:\n",
      " |          - The model architecture, allowing to re-instantiate the model.\n",
      " |          - The model weights.\n",
      " |          - The state of the optimizer, allowing to resume training\n",
      " |              exactly where you left off.\n",
      " |      \n",
      " |      This allows you to save the entirety of the state of a model\n",
      " |      in a single file.\n",
      " |      \n",
      " |      Saved models can be reinstantiated via `keras.models.load_model`.\n",
      " |      The model returned by `load_model`\n",
      " |      is a compiled model ready to be used (unless the saved model\n",
      " |      was never compiled in the first place).\n",
      " |      \n",
      " |      # Arguments\n",
      " |          filepath: String, path to the file to save the weights to.\n",
      " |          overwrite: Whether to silently overwrite any existing file at the\n",
      " |              target location, or provide the user with a manual prompt.\n",
      " |          include_optimizer: If True, save optimizer's state together.\n",
      " |      \n",
      " |      # Example\n",
      " |      \n",
      " |      ```python\n",
      " |      from keras.models import load_model\n",
      " |      \n",
      " |      model.save('my_model.h5')  # creates a HDF5 file 'my_model.h5'\n",
      " |      del model  # deletes the existing model\n",
      " |      \n",
      " |      # returns a compiled model\n",
      " |      # identical to the previous one\n",
      " |      model = load_model('my_model.h5')\n",
      " |      ```\n",
      " |  \n",
      " |  save_weights(self, filepath, overwrite=True)\n",
      " |      Dumps all layer weights to a HDF5 file.\n",
      " |      \n",
      " |      The weight file has:\n",
      " |          - `layer_names` (attribute), a list of strings\n",
      " |              (ordered names of model layers).\n",
      " |          - For every layer, a `group` named `layer.name`\n",
      " |              - For every such layer group, a group attribute `weight_names`,\n",
      " |                  a list of strings\n",
      " |                  (ordered names of weights tensor of the layer).\n",
      " |              - For every weight in the layer, a dataset\n",
      " |                  storing the weight value, named after the weight tensor.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          filepath: String, path to the file to save the weights to.\n",
      " |          overwrite: Whether to silently overwrite any existing file at the\n",
      " |              target location, or provide the user with a manual prompt.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ImportError: If h5py is not available.\n",
      " |  \n",
      " |  set_weights(self, weights)\n",
      " |      Sets the weights of the model.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          weights: A list of Numpy arrays with shapes and types matching\n",
      " |              the output of `model.get_weights()`.\n",
      " |  \n",
      " |  summary(self, line_length=None, positions=None, print_fn=None)\n",
      " |      Prints a string summary of the network.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          line_length: Total length of printed lines\n",
      " |              (e.g. set this to adapt the display to different\n",
      " |              terminal window sizes).\n",
      " |          positions: Relative or absolute positions of log elements\n",
      " |              in each line. If not provided,\n",
      " |              defaults to `[.33, .55, .67, 1.]`.\n",
      " |          print_fn: Print function to use.\n",
      " |              It will be called on each line of the summary.\n",
      " |              You can set it to a custom function\n",
      " |              in order to capture the string summary.\n",
      " |              It defaults to `print` (prints to stdout).\n",
      " |  \n",
      " |  to_json(self, **kwargs)\n",
      " |      Returns a JSON string containing the network configuration.\n",
      " |      \n",
      " |      To load a network from a JSON save file, use\n",
      " |      `keras.models.model_from_json(json_string, custom_objects={})`.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          **kwargs: Additional keyword arguments\n",
      " |              to be passed to `json.dumps()`.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A JSON string.\n",
      " |  \n",
      " |  to_yaml(self, **kwargs)\n",
      " |      Returns a yaml string containing the network configuration.\n",
      " |      \n",
      " |      To load a network from a yaml save file, use\n",
      " |      `keras.models.model_from_yaml(yaml_string, custom_objects={})`.\n",
      " |      \n",
      " |      `custom_objects` should be a dictionary mapping\n",
      " |      the names of custom losses / layers / etc to the corresponding\n",
      " |      functions / classes.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          **kwargs: Additional keyword arguments\n",
      " |              to be passed to `yaml.dump()`.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A YAML string.\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Class methods inherited from keras.engine.topology.Container:\n",
      " |  \n",
      " |  from_config(config, custom_objects=None) from builtins.type\n",
      " |      Instantiates a Model from its config (output of `get_config()`).\n",
      " |      \n",
      " |      # Arguments\n",
      " |          config: Model config dictionary.\n",
      " |          custom_objects: Optional dictionary mapping names\n",
      " |              (strings) to custom classes or functions to be\n",
      " |              considered during deserialization.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A model instance.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: In case of improperly formatted config dict.\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data descriptors inherited from keras.engine.topology.Container:\n",
      " |  \n",
      " |  input_spec\n",
      " |      Gets the model's input specs.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A list of `InputSpec` instances (one per input to the model)\n",
      " |              or a single instance if the model has only one input.\n",
      " |  \n",
      " |  losses\n",
      " |      Retrieves the model's losses.\n",
      " |      \n",
      " |      Will only include losses that are either\n",
      " |      inconditional, or conditional on inputs to this model\n",
      " |      (e.g. will not include losses that depend on tensors\n",
      " |      that aren't inputs to this model).\n",
      " |      \n",
      " |      # Returns\n",
      " |          A list of loss tensors.\n",
      " |  \n",
      " |  non_trainable_weights\n",
      " |  \n",
      " |  state_updates\n",
      " |      Returns the `updates` from all layers that are stateful.\n",
      " |      \n",
      " |      This is useful for separating training updates and\n",
      " |      state updates, e.g. when we need to update a layer's internal state\n",
      " |      during prediction.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A list of update ops.\n",
      " |  \n",
      " |  stateful\n",
      " |  \n",
      " |  trainable_weights\n",
      " |  \n",
      " |  updates\n",
      " |      Retrieves the model's updates.\n",
      " |      \n",
      " |      Will only include updates that are either\n",
      " |      inconditional, or conditional on inputs to this model\n",
      " |      (e.g. will not include updates that depend on tensors\n",
      " |      that aren't inputs to this model).\n",
      " |      \n",
      " |      # Returns\n",
      " |          A list of update ops.\n",
      " |  \n",
      " |  uses_learning_phase\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Methods inherited from keras.engine.topology.Layer:\n",
      " |  \n",
      " |  __call__(self, inputs, **kwargs)\n",
      " |      Wrapper around self.call(), for handling internal references.\n",
      " |      \n",
      " |      If a Keras tensor is passed:\n",
      " |          - We call self._add_inbound_node().\n",
      " |          - If necessary, we `build` the layer to match\n",
      " |              the _keras_shape of the input(s).\n",
      " |          - We update the _keras_shape of every input tensor with\n",
      " |              its new shape (obtained via self.compute_output_shape).\n",
      " |              This is done as part of _add_inbound_node().\n",
      " |          - We update the _keras_history of the output tensor(s)\n",
      " |              with the current layer.\n",
      " |              This is done as part of _add_inbound_node().\n",
      " |      \n",
      " |      # Arguments\n",
      " |          inputs: Can be a tensor or list/tuple of tensors.\n",
      " |          **kwargs: Additional keyword arguments to be passed to `call()`.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Output of the layer's `call` method.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: in case the layer is missing shape information\n",
      " |              for its `build` call.\n",
      " |  \n",
      " |  add_loss(self, losses, inputs=None)\n",
      " |      Adds losses to the layer.\n",
      " |      \n",
      " |      The loss may potentially be conditional on some inputs tensors,\n",
      " |      for instance activity losses are conditional on the layer's inputs.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          losses: loss tensor or list of loss tensors\n",
      " |              to add to the layer.\n",
      " |          inputs: input tensor or list of inputs tensors to mark\n",
      " |              the losses as conditional on these inputs.\n",
      " |              If None is passed, the loss is assumed unconditional\n",
      " |              (e.g. L2 weight regularization, which only depends\n",
      " |              on the layer's weights variables, not on any inputs tensors).\n",
      " |  \n",
      " |  add_update(self, updates, inputs=None)\n",
      " |      Adds updates to the layer.\n",
      " |      \n",
      " |      The updates may potentially be conditional on some inputs tensors,\n",
      " |      for instance batch norm updates are conditional on the layer's inputs.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          updates: update op or list of update ops\n",
      " |              to add to the layer.\n",
      " |          inputs: input tensor or list of inputs tensors to mark\n",
      " |              the updates as conditional on these inputs.\n",
      " |              If None is passed, the updates are assumed unconditional.\n",
      " |  \n",
      " |  add_weight(self, name, shape, dtype=None, initializer=None, regularizer=None, trainable=True, constraint=None)\n",
      " |      Adds a weight variable to the layer.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          name: String, the name for the weight variable.\n",
      " |          shape: The shape tuple of the weight.\n",
      " |          dtype: The dtype of the weight.\n",
      " |          initializer: An Initializer instance (callable).\n",
      " |          regularizer: An optional Regularizer instance.\n",
      " |          trainable: A boolean, whether the weight should\n",
      " |              be trained via backprop or not (assuming\n",
      " |              that the layer itself is also trainable).\n",
      " |          constraint: An optional Constraint instance.\n",
      " |      \n",
      " |      # Returns\n",
      " |          The created weight variable.\n",
      " |  \n",
      " |  assert_input_compatibility(self, inputs)\n",
      " |      Checks compatibility between the layer and provided inputs.\n",
      " |      \n",
      " |      This checks that the tensor(s) `input`\n",
      " |      verify the input assumptions of the layer\n",
      " |      (if any). If not, exceptions are raised.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          inputs: input tensor or list of input tensors.\n",
      " |      \n",
      " |      # Raises\n",
      " |          ValueError: in case of mismatch between\n",
      " |              the provided inputs and the expectations of the layer.\n",
      " |  \n",
      " |  build(self, input_shape)\n",
      " |      Creates the layer weights.\n",
      " |      \n",
      " |      Must be implemented on all layers that have weights.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          input_shape: Keras tensor (future input to layer)\n",
      " |              or list/tuple of Keras tensors to reference\n",
      " |              for weight shape computations.\n",
      " |  \n",
      " |  count_params(self)\n",
      " |      Counts the total number of scalars composing the weights.\n",
      " |      \n",
      " |      # Returns\n",
      " |          An integer count.\n",
      " |      \n",
      " |      # Raises\n",
      " |          RuntimeError: if the layer isn't yet built\n",
      " |              (in which case its weights aren't yet defined).\n",
      " |  \n",
      " |  get_input_at(self, node_index)\n",
      " |      Retrieves the input tensor(s) of a layer at a given node.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          node_index: Integer, index of the node\n",
      " |              from which to retrieve the attribute.\n",
      " |              E.g. `node_index=0` will correspond to the\n",
      " |              first time the layer was called.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A tensor (or list of tensors if the layer has multiple inputs).\n",
      " |  \n",
      " |  get_input_mask_at(self, node_index)\n",
      " |      Retrieves the input mask tensor(s) of a layer at a given node.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          node_index: Integer, index of the node\n",
      " |              from which to retrieve the attribute.\n",
      " |              E.g. `node_index=0` will correspond to the\n",
      " |              first time the layer was called.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A mask tensor\n",
      " |          (or list of tensors if the layer has multiple inputs).\n",
      " |  \n",
      " |  get_input_shape_at(self, node_index)\n",
      " |      Retrieves the input shape(s) of a layer at a given node.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          node_index: Integer, index of the node\n",
      " |              from which to retrieve the attribute.\n",
      " |              E.g. `node_index=0` will correspond to the\n",
      " |              first time the layer was called.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A shape tuple\n",
      " |          (or list of shape tuples if the layer has multiple inputs).\n",
      " |  \n",
      " |  get_losses_for(self, inputs)\n",
      " |  \n",
      " |  get_output_at(self, node_index)\n",
      " |      Retrieves the output tensor(s) of a layer at a given node.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          node_index: Integer, index of the node\n",
      " |              from which to retrieve the attribute.\n",
      " |              E.g. `node_index=0` will correspond to the\n",
      " |              first time the layer was called.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A tensor (or list of tensors if the layer has multiple outputs).\n",
      " |  \n",
      " |  get_output_mask_at(self, node_index)\n",
      " |      Retrieves the output mask tensor(s) of a layer at a given node.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          node_index: Integer, index of the node\n",
      " |              from which to retrieve the attribute.\n",
      " |              E.g. `node_index=0` will correspond to the\n",
      " |              first time the layer was called.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A mask tensor\n",
      " |          (or list of tensors if the layer has multiple outputs).\n",
      " |  \n",
      " |  get_output_shape_at(self, node_index)\n",
      " |      Retrieves the output shape(s) of a layer at a given node.\n",
      " |      \n",
      " |      # Arguments\n",
      " |          node_index: Integer, index of the node\n",
      " |              from which to retrieve the attribute.\n",
      " |              E.g. `node_index=0` will correspond to the\n",
      " |              first time the layer was called.\n",
      " |      \n",
      " |      # Returns\n",
      " |          A shape tuple\n",
      " |          (or list of shape tuples if the layer has multiple outputs).\n",
      " |  \n",
      " |  get_updates_for(self, inputs)\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data descriptors inherited from keras.engine.topology.Layer:\n",
      " |  \n",
      " |  __dict__\n",
      " |      dictionary for instance variables (if defined)\n",
      " |  \n",
      " |  __weakref__\n",
      " |      list of weak references to the object (if defined)\n",
      " |  \n",
      " |  built\n",
      " |  \n",
      " |  input\n",
      " |      Retrieves the input tensor(s) of a layer.\n",
      " |      \n",
      " |      Only applicable if the layer has exactly one inbound node,\n",
      " |      i.e. if it is connected to one incoming layer.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Input tensor or list of input tensors.\n",
      " |      \n",
      " |      # Raises\n",
      " |          AttributeError: if the layer is connected to\n",
      " |          more than one incoming layers.\n",
      " |  \n",
      " |  input_mask\n",
      " |      Retrieves the input mask tensor(s) of a layer.\n",
      " |      \n",
      " |      Only applicable if the layer has exactly one inbound node,\n",
      " |      i.e. if it is connected to one incoming layer.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Input mask tensor (potentially None) or list of input\n",
      " |          mask tensors.\n",
      " |      \n",
      " |      # Raises\n",
      " |          AttributeError: if the layer is connected to\n",
      " |          more than one incoming layers.\n",
      " |  \n",
      " |  input_shape\n",
      " |      Retrieves the input shape tuple(s) of a layer.\n",
      " |      \n",
      " |      Only applicable if the layer has exactly one inbound node,\n",
      " |      i.e. if it is connected to one incoming layer.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Input shape tuple\n",
      " |          (or list of input shape tuples, one tuple per input tensor).\n",
      " |      \n",
      " |      # Raises\n",
      " |          AttributeError: if the layer is connected to\n",
      " |          more than one incoming layers.\n",
      " |  \n",
      " |  output\n",
      " |      Retrieves the output tensor(s) of a layer.\n",
      " |      \n",
      " |      Only applicable if the layer has exactly one inbound node,\n",
      " |      i.e. if it is connected to one incoming layer.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Output tensor or list of output tensors.\n",
      " |      \n",
      " |      # Raises\n",
      " |          AttributeError: if the layer is connected to\n",
      " |          more than one incoming layers.\n",
      " |  \n",
      " |  output_mask\n",
      " |      Retrieves the output mask tensor(s) of a layer.\n",
      " |      \n",
      " |      Only applicable if the layer has exactly one inbound node,\n",
      " |      i.e. if it is connected to one incoming layer.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Output mask tensor (potentially None) or list of output\n",
      " |          mask tensors.\n",
      " |      \n",
      " |      # Raises\n",
      " |          AttributeError: if the layer is connected to\n",
      " |          more than one incoming layers.\n",
      " |  \n",
      " |  output_shape\n",
      " |      Retrieves the output shape tuple(s) of a layer.\n",
      " |      \n",
      " |      Only applicable if the layer has one inbound node,\n",
      " |      or if all inbound nodes have the same output shape.\n",
      " |      \n",
      " |      # Returns\n",
      " |          Output shape tuple\n",
      " |          (or list of input shape tuples, one tuple per output tensor).\n",
      " |      \n",
      " |      # Raises\n",
      " |          AttributeError: if the layer is connected to\n",
      " |          more than one incoming layers.\n",
      " |  \n",
      " |  weights\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
